测试 xmm 寄存器中的任何字节是否为 0

Test if any byte in an xmm register is 0

我目前正在自学 SIMD,并且正在编写一个相当简单的字符串处理子例程。然而,我 仅限于 SSE2,这使我无法利用 ptest 找到空终端。

我目前尝试查找空终端的方式使我的 SIMD 循环有超过 16 条指令,这违背了使用 SIMD 的目的 - 或者至少使它不那么值得。

//Check for null byte
pxor xmm4, xmm4
pcmpeqb xmm4, [rdi]                                   //Generate bitmask
movq rax, xmm4
test rax, 0xffffffffffffffff                          //Test low qword
jnz .Lepilogue
movhlps xmm4, xmm4                                    //Move high into low qword
movq rax, xmm4
test rax, 0xffffffffffffffff                          //Test high qword
jz .LsimdLoop                                         //No terminal was found, keep looping

我想知道在没有 ptest 的情况下是否有更快的方法来执行此操作,或者这是否是最好的方法,我将不得不进一步优化循环的其余部分。

注意:我确保输入使用 SIMD 的循环的字符串地址是 16B 对齐的,以允许对齐指令。

您可以使用_mm_movemask_epi8pmovmskb指令)从比较结果中获取位掩码(生成的掩码包含向量中每个字节的最高有效位)。然后,测试是否有任何字节为零意味着测试掩码中的 16 位是否有任何非零。

pxor xmm4, xmm4
pcmpeqb xmm4, [rdi]
pmovmskb eax, xmm4
test eax, eax          ; ZF=0 if there are any set bits = any matches
jnz .found_a_zero

找到任意匹配的vector后,可以找到第一个匹配positionbsf eax,eax得到bitmask中的bit-index,也就是16 字节向量中的字节索引。

或者,您可以使用 pcmpeqb / pmovmskb / cmp eax, 0xffff 检查是否设置了 所有 位,而不是检查至少设置了 1 位。