AVX512BW:使用bsf / tzcnt处理32位代码中的64位掩码?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AVX512BW:使用bsf / tzcnt处理32位代码中的64位掩码?相关的知识,希望对你有一定的参考价值。
这是我的AVX512BW中'strlen'函数的代码
vxorps zmm0, zmm0, zmm0 ; ZMM0 = 0
vpcmpeqb k0, zmm0, [ebx] ; ebx is string and it's aligned at 64-byte boundary
kortestq k0, k0 ; 0x00 found ?
jnz .chk_0x00
现在为'chk_0x00',在x86_64系统中,没有问题,我们可以这样处理:
chk_0x00:
kmovq rbx, k0
tzcnt rbx, rbx
add rax, rbx
这里我们有一个64位寄存器,因此我们可以将掩码存储到其中,但是我的问题是关于x86系统,因为我们没有任何64位寄存器,因此我们必须使用'内存'保留(8字节),一次检查两个掩码的两个DWORD(实际上,这是我的方式,我想知道是否还有更好的方法)
chk_0x00:
kmovd ebx, k0 ; move the first dword of the mask to the ebx
test ebx, ebx ; 0x00 found in the first dword ?
jz .check_next_dword
bsf ebx, ebx
add eax, ebx
jmp .done
.check_next_dword:
add eax, 32 ; 0x00 is not found in the first DWORD of the mask so we pass it by adding 32 to the length
sub esp, 8 ; reserve 8-byte from memory
kmovq [esp], k0 ; move the 8-byte MASK from k0 to our reserved memory
mov ebx, [esp+4] ; move the second DWORD of the mask to the ebx
bsf ebx, ebx
add eax, ebx
add esp, 8
以我的x86方式,我使用'kmovd'将掩码的第一个DWORD移到ebx中,但是我不知道该掩码的第二个DWORD要做什么!所以我只是从内存中保留了8字节并将掩码(8字节)移入其中,然后将第二个dword移入ebx并再次检查了它……还有更好的解决方案吗? (我认为我的方法还不够快)使用vxorps
初始化为零的zmm
寄存器是否正确?
答案
类似于KSHIFTRQ的视图可以用作替代方案,以将k0
计数器的高32位右移为较低的32位,可以将其复制到常规用途寄存器中。喜欢:
.check_next_dword:
add eax, 32
KSHIFTRQ k0, k0, 32 ;shift hi 32 bits to be low 32 bits
kmovd ebx, k0
...
是的,vxorps zmm0, zmm0, zmm0
会将zmm0
设置为零,因为根据vxorps referense,它是将第三个参数不带掩码的异或(您也可以检查此SO question关于将zmm寄存器清零)]
以上是关于AVX512BW:使用bsf / tzcnt处理32位代码中的64位掩码?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 AVX512 寄存器 zmm26 中的 QuadWord 写入 rax 寄存器?