Z b*_*son 12
虽然使用_mm_movemask_epi8
是一种解决方案,但如果你有一个带SSE4.1的处理器,我认为更好的解决方案是使用一条指令来设置FLAGS寄存器中的零或进位标志.这节省了一条test
或cmp
指令.
要做到这一点,你可以这样做:
if(_mm_test_all_ones(_mm_cmpeq_epi8(v1,v2))) {
//v0 == v1
}
Run Code Online (Sandbox Code Playgroud)
编辑:正如Paul R指出的那样_mm_test_all_ones
生成两条指令:pcmpeqd
和ptest
.有了 _mm_cmpeq_epi8
这三条指令总数.这是一个更好的解决方案,总共只使用两条指令:
__m128i neq = _mm_xor_si128(v1,v2);
if(_mm_test_all_zeros(neq,neq)) {
//v0 == v1
}
Run Code Online (Sandbox Code Playgroud)
这会产生
pxor %xmm1, %xmm0
ptest %xmm0, %xmm0
Run Code Online (Sandbox Code Playgroud)
Pau*_*l R 10
您可以使用比较,然后从比较结果中提取掩码:
__m128i vcmp = _mm_cmpeq_epi8(v0, v1); // PCMPEQB
uint16_t vmask = _mm_movemask_epi8(vcmp); // PMOVMSKB
if (vmask == 0xffff)
{
// v0 == v1
}
Run Code Online (Sandbox Code Playgroud)
这适用于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
}
Run Code Online (Sandbox Code Playgroud)
我只是在Haswell Core i7上对这两个实现进行基准测试,使用clang来编译测试工具并且时序结果非常相似 - SSE4实现似乎稍微快一些,但很难衡量差异.