【问题标题】:Check XMM register for all zeroes检查 XMM 寄存器是否全为零
【发布时间】:2012-04-27 21:02:14
【问题描述】:

有没有办法检查 __m128i 变量中的所有位/字节/字等是否为 0?
在我的应用程序中,我必须检查 __m128i 变量中包含的所有整数是否为零。我必须提取它们并分别比较它们吗?


编辑:

我现在做的是:

int next = 0;
do{
    //some code

    next = idata.m128i_i32[0] + idata.m128i_i32[1] + idata.m128i_i32[2] + idata.m128i_i32[3];
}while(next > 0);

我需要检查idata 是否全为零,而无需访问每个单独的元素,如果它们是则退出循环......


根据 Harold 的评论,这是解决方案:

__m128i idata = _mm_setr_epi32(i,j,k,l);
do{
    //some code
}while( !_mm_testz_si128(idata, idata) );

如果idata 中每个 DW 的所有低位均为 0,这将退出循环...谢谢 harold!

【问题讨论】:

  • 你不能使用PCMPEQD 来比较而不进行提取吗?
  • XMM 寄存器是否附加了标志寄存器?如果是,则这些位之间必须有一个零标志。
  • 查看PTEST 是否可以使用 SSE4,否则需要花费更多精力。
  • 您不需要为PTEST 的第二个参数初始化一个虚拟参数,即您可以使用_mm_testz_si128(idata, idata) 而不是_mm_testz_si128(idata, _mm_set1_epi32(0xFFFF))

标签: c++ sse simd intrinsics


【解决方案1】:

_mm_testz_si128 是 SSE4.1,某些 CPU(例如 Intel Atom、AMD Phenom)不支持它

这是一个与 SSE2 兼容的变体

inline bool isAllZeros(__m128i xmm) {
    return _mm_movemask_epi8(_mm_cmpeq_epi8(xmm, _mm_setzero_si128())) == 0xFFFF;
}

【讨论】:

    【解决方案2】:

    就像 Paul R 对我原来的帖子发表的评论一样:

    “您不需要为PTEST 的第二个参数初始化一个虚拟参数,也就是说,您可以只针对自身测试一个值,而不是_mm_testz_si128(idata, _mm_set1_epi32(0xFFFF))。”

    ptest 用一条指令完成整个工作。

    这有帮助。

    【讨论】:

      猜你喜欢
      • 2012-07-22
      • 2017-07-08
      • 1970-01-01
      • 1970-01-01
      • 2020-10-03
      • 1970-01-01
      • 2015-06-28
      • 1970-01-01
      • 2017-10-29
      相关资源
      最近更新 更多