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位掩码?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法用avx2自动替换avx512?

动态确定恶意 AVX-512 指令的执行位置

AVX2 和 AVX-512 有啥区别?

如何将 AVX512 寄存器 zmm26 中的 QuadWord 写入 rax 寄存器?

如何编译 TensorFlow 二进制文件以使用 AVX2、AVX512F、FMA?

使用 AVX512 或 AVX2 计算所有压缩 32 位整数之和的最快方法