在__m128i向量上水平检查零?

时间:2014-04-21 21:34:17

标签: c++ intel vectorization sse avx

我有几个包含32位无符号整数的__m128i向量,我想检查4个整数中的任何一个是否为零。

我理解如何“聚合”多个__m128i向量,但最终我仍然会得到一个__m128i向量,然后我需要水平检查。

如何在最后一个向量中执行最后的水平检查?

编辑我使用的是英特尔内在函数,而不是内联汇编

1 个答案:

答案 0 :(得分:5)

不要这样做。尽可能避免水平操作;它是矢量代码性能的死亡。

相反,将矢量与零矢量进行比较,然后使用PMOVMSKB在GPR中获取掩码。如果该掩码不为零,则向量的至少一个通道为零:

__m128i yourVector;
__m128i zeroVector = _mm_set1_epi32(0);

if (_mm_movemask_epi8(_mm_cmpeq_epi32(yourVector,zeroVector))) {
    // at least one lane of your vector is zero.
}

如果你想假设SSE4.1,你也可以使用PTEST。


从表面上看问题,如果你真的需要做横向的,出于某种原因,它将是movhlps + andps + shufps + andps。但不要这样做。