测试两个__m128i变量之间的相等性

时间:2014-11-12 06:44:01

标签: c x86 sse simd

如果我想在两个__m128i变量之间进行逐位相等测试,我是否需要使用SSE指令,还是可以使用==?如果没有,我应该使用哪条SSE指令?

3 个答案:

答案 0 :(得分:11)

尽管使用_mm_movemask_epi8是一种解决方案,但如果你有一个带SSE4.1的处理器,我认为更好的解决方案是使用一条指令来设置FLAGS寄存器中的零或进位标志。 This saves a test or cmp instruction

要做到这一点,你可以这样做:

if(_mm_test_all_ones(_mm_cmpeq_epi8(v1,v2))) {
    //v0 == v1
}

编辑:正如Paul R所指出的那样_mm_test_all_ones生成两条指令:pcmpeqdptest_mm_cmpeq_epi8总共有三条指令。这是一个更好的解决方案,总共只使用两条指令:

__m128i neq = _mm_xor_si128(v1,v2);
if(_mm_test_all_zeros(neq,neq)) {
    //v0 == v1
}

这会生成

pxor    %xmm1, %xmm0
ptest   %xmm0, %xmm0

答案 1 :(得分:10)

您可以使用比较,然后从比较结果中提取掩码:

__m128i vcmp = _mm_cmpeq_epi8(v0, v1);       // PCMPEQB
uint16_t vmask = _mm_movemask_epi8(vcmp);    // PMOVMSKB
if (vmask == 0xffff)
{
    // v0 == v1
}

这适用于SSE2及更高版本。

如@Zboson所述,如果您有SSE 4.1,那么您可以这样做,可能稍微更高效,因为它是两个SSE指令然后进行测试国旗(ZF):

__m128i vcmp = _mm_xor_si128(v0, v1);        // PXOR
if (_mm_testz_si128(vcmp, vcmp))             // PTEST (requires SSE 4.1)
{
    // v0 == v1
}

FWIW我只是在Haswell Core i7上对这两个实现进行了基准测试,使用clang来编译测试工具并且时序结果非常相似 - SSE4实现似乎稍微快一些,但很难测量差。

答案 2 :(得分:-1)

考虑使用SSE4.1指令ptest

if(_mm_testc_si128(v0, v1)) {if equal}

else {if not} 

ptest计算a和掩码中128位(表示整数数据)的按位AND,如果结果为零则返回1,否则返回0.