向量化涉及短裤的条件
Posted
技术标签:
【中文标题】向量化涉及短裤的条件【英文标题】:Vectorizing a conditional involving shorts 【发布时间】:2012-12-21 16:09:57 【问题描述】:我正在使用 2 个无符号短裤的紧凑结构来指示开始和结束位置。
我需要能够快速确定是否有任何 Range
对象的长度(从开始到结束的差异)超过阈值。
我将拥有大量对象,每个对象都有自己的Range
数组,因此在列表或其他内容中跟踪哪些Range
对象高于阈值是不可行的。这段代码也会经常运行(每个数组每秒运行很多次),所以它需要高效。
struct Range
unsigned short start;
unsigned short end;
我将始终拥有一个大小为 2^n 的 Range
数组。虽然我想在发现超过阈值的东西后立即中止,但我很确定将它们简单地或全部放在一起并在最后检查会更快......假设我可以对循环进行矢量化。虽然如果我可以对每个向量的结果块做一个 if 语句,那就太好了。
size_t rangecount = 1 << resolution;
Range* ranges = new Range[rangecount];
...
bool result = false;
for (size_t i = 0; i < ranges; ++i)
result |= (range[i].end - range[i].start) > 4;
毫不奇怪,自动矢量化器会给出 1202 错误,因为我的数据类型不是 32 位或 64 位宽。我真的不想将我的数据大小加倍并使每个字段都成为无符号整数。所以我猜想自动矢量化方法已经过时了。
是否有可以处理 16 位变量的向量指令?如果有,我如何在 c++ 中使用它们来矢量化我的循环?
【问题讨论】:
您需要将范围值存储在数组中吗?为什么不将它们存储在另一个可以加快查找速度的数据结构中? 因此在列表或某事中跟踪哪些 Range 对象高于阈值是不可行的。如果您只想确定您是否有违反规则的范围,然后跟踪它。您不必跟踪每个对象来执行此操作。 您多久使用一次end
?切换到(start,size)
表示而不是(start,end)
是否可行。当然,您每次使用时都需要计算end
,但如果end
与size
的相对使用率较低,那仍然可能是一场胜利......
我建议给Range
一个返回大小的成员函数size() const
(begin() const
和end() const
相同)。然后,您可以轻松安全地在存储结尾的内部表示与存储大小的内部表示之间进行切换,具体取决于哪个最终被更频繁地使用。
【参考方案1】:
您想知道是否有任何值大于 4?
是的,对此有 SIMD 指令。不幸的是,自动矢量化无法处理这种情况。这是一个矢量化算法:
diff_v = end_v - start_v; // _mm_hsub_epi16
floor_v = max(4_v, diff_v); // _mm_max_epi16
if (floor_v != 4_v) return true; // wide scalar comparison
将_mm_sub_epi16
与数组结构一起使用,或将_mm_hsub_epi16
与结构数组一起使用。
实际上,由于start
首先存储在内存中,因此您将处理start_v - end_v
,因此请使用_mm_min_epi16
和-4
的向量。
每条 SSE3 指令一次将执行 8 次比较。提前返回而不是循环仍然是最快的。但是,多展开循环可能会为您带来额外的速度(将第一组结果传递给打包的 min/max 函数以组合它们)。
所以你最终得到(大约):
most_negative = threshold = _mm_set_epi64(0xFCFCFCFCFCFCFCFC); // vectorized -4
loop:
a = load from range;
b = load from range;
diff = _mm_hsub_epi16(a, b);
most_negative = _mm_min_epi16(most_negative, diff);
// unroll by repeating the above four instructions 4 times or so
if (most_negative != threshold) return true;
repeat loop
【讨论】:
对于自动矢量化器无法做到的事情,这看起来很简单! @user173342:处理只有两个成员的交错数组是一种特殊情况,自动矢量化器可能还没有准备好。以上是关于向量化涉及短裤的条件的主要内容,如果未能解决你的问题,请参考以下文章