- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在使用 2 个无符号短裤的紧凑结构,指示开始和结束位置。
我需要能够快速确定是否有任何长度(从开始到结束的差异)超过阈值的 Range
对象。
我将拥有大量对象,每个对象都有自己的 Range
数组,因此跟踪哪些 Range
对象超出阈值是不可行的列表或其他东西。此代码也将经常运行(每个数组每秒多次),因此需要高效。
struct Range
{
unsigned short start;
unsigned short end;
}
我将始终拥有一个大小为 2^n 的 Range
数组。虽然我想在发现超过阈值的情况下立即中止,但我很确定将它们简单地或在一起并在最后检查会更快......假设我可以矢量化循环。尽管如果我可以对每个 vector 的结果 block 执行 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 位变量的 vector 指令?如果有,我如何在 C++ 中使用它们来矢量化我的循环?
最佳答案
您想知道是否有任何值大于 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
的 vector .
每条 SSE3 指令将一次执行 8 次比较。提前返回而不是循环仍然是最快的。然而,将循环展开得更多一点可能会给你带来额外的速度(将第一组结果传递到打包的最小/最大函数中以组合它们)。
所以你最终得到(大约):
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
关于c++ - 向量化涉及短裤的条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13993445/
我将如何编写一段代码来与短片的第一个字节而不是第二部分? 例子:我有一个名为 inputShort 的 short,我希望这个 short 删除第二个字节中的所有值。所以我想用逻辑运算符将其与。 好吧
我写了一些使用字符串表示时间的代码,例如“0620”,但经过仔细思考后我意识到这些可以解析为短裤以比较性能和存储 yield 。 在单元测试中,我将一个短写为 0620 的值与返回值 620 进行比较
我是一名优秀的程序员,十分优秀!