【发布时间】:2018-04-27 18:01:28
【问题描述】:
我编写了一个算法,该算法使用英特尔内在函数并行执行多个单精度运算。我的算法每次迭代的结果是单个 256 位向量 (__m256) 中非零条目的数量。
例如:
00000000 FFFFFFFF 00000000 00000000 00000000 FFFFFFFF FFFFFFFF FFFFFFFF
其中迭代的结果是 4。
计算向量中非零条目数量的最快方法是什么?
目前我正在做这样的事情:
float results[8];
_mm256_storeu_ps(results, result_vector);
int count = 0;
for (uint32_t idx = 0; idx < 8; ++idx)
{
if (results[idx] != 0)
{
++count;
}
}
这种方法效果很好,但我想知道是否有更有效的方法,也许不涉及商店。
【问题讨论】:
-
非零条目是否保证为
0xFFFFFFFF?如果是这样,一个想法是使用掩码与以隔离每个 32 位部分中的最低有效位,然后应用绝对差之和。 -
或者只与零比较 (
_mm256_cmp_ps),提取位掩码 (_mm256_movemask_ps) 并使用popcnt计算位?三个指令。 -
如果它们已经是 0 / 0xFFF...(即比较的结果),您可以跳过
cmpps步骤,只需 movemask / popcnt。 -
@PaulR 我不知道 movemask 内在; that + popcnt 完美运行,谢谢!
-
@PeterCordes 是的,结果要么是 0,要么是全 0xF,所以不需要比较
标签: algorithm vector simd avx avx2