在__m128i向量上水平检查零?

use*_*112 0 c++ sse intel vectorization avx

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

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

如何在最后一个矢量上执行零的最终水平检查?

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

Ste*_*non 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.
}
Run Code Online (Sandbox Code Playgroud)

如果要假设SSE4.1,也可以使用PTEST.


从表面上看问题,如果你确实需要做横向和由于某种原因,那将是movhlps + andps + shufps + andps.但是不要这样做.

  • @StephenCanon听起来这是一个更大的矢量的减少.最后,你仍然需要减少一个向量.但在这种情况下,它可能不是性能关键,因为它是O(1)的O(N)操作. (2认同)