测试 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_epi8
(pmovmskb
指令)从比较结果中获取位掩码(生成的掩码包含向量中每个字节的最高有效位)。然后,测试是否有任何字节为零意味着测试掩码中的 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后,可以找到第一个匹配position和bsf eax,eax
得到bitmask中的bit-index,也就是16 字节向量中的字节索引。
或者,您可以使用 pcmpeqb
/ pmovmskb
/ cmp eax, 0xffff
检查是否设置了 所有 位,而不是检查至少设置了 1 位。
我目前正在自学 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_epi8
(pmovmskb
指令)从比较结果中获取位掩码(生成的掩码包含向量中每个字节的最高有效位)。然后,测试是否有任何字节为零意味着测试掩码中的 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后,可以找到第一个匹配position和bsf eax,eax
得到bitmask中的bit-index,也就是16 字节向量中的字节索引。
或者,您可以使用 pcmpeqb
/ pmovmskb
/ cmp eax, 0xffff
检查是否设置了 所有 位,而不是检查至少设置了 1 位。