assembly - 如何在ZMM寄存器上实现vpmovmskb的效果?

标签 assembly x86 bitmask avx512

古怪的指令 (v)pmovmskb 可追溯到 SSE,它获取 mm、xmm 或 ymm 寄存器中字节的最高有效位,并将它们移动到通用寄存器中。这对于分类向量元素或执行 SWAR 非常有用。对单个位的操作。具体来说,我在 previous answer 中使用了这个指令。计算位置人口计数。
不幸的是,这条指令还没有扩展到 ZMM 寄存器,并且出人意料地没有出现在 AVX-512 名册中。如何有效地模拟 ZMM 寄存器的效果?我有哪些类似/其他选择?

最佳答案

在 AVX512BW 中有一个指令,只是名称不同。 _mm512_movepi8_mask/
vpmovb2m k, zmm ,可用于从字节到 qword 的每个元素大小。
(AVX512DQ 适用于 D 和 Q 版本,AVX512BW 适用于 B 和 W 版本)。
还有 mask->vector inverse movemask, vpmovm2b (再次适用于所有元素尺寸)。

AVX512当然也有各种cmptest进入掩码说明,所以用set1_epi8(1<<n)向量,您可以使用 vptestmb k2{k1}, zmm2, zmm3/m512 将任何位位置抓取到掩码寄存器中; _mm512_test_epi8_mask .请注意,与 vpmov2bm 不同,它支持对目标进行零掩码以有效地与另一个 k 进行 AND 运算。免费掩码,因此即使您只想要高位,也可能值得使用。
还有一个NAND版本 vptestnmb .这些 D 和 Q 版本支持广播内存源操作数,但 B 和 W 版本不支持。
使用 8 个不同的掩码常量,您可以在展开的循环中提取不同的位,而无需花费任何移位指令。或者您可以从不同的元素中提取不同的位。
这些都是 AVX512BW,在 Skylake-AVX512 之后的 AVX512 CPU 上可用,但不是 Xeon Phi (KNL/KNM)。

关于assembly - 如何在ZMM寄存器上实现vpmovmskb的效果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63300449/

相关文章:

c# - 当位掩码(标志)枚举变得太大时该怎么办

c - C 中的位操作 - 内置函数

assembly - DosBox 有问题,int 15h ah = 86h

c++ - 关于反汇编输出的问题

c - 当您使用稍后分配给全局的临时值时,GCC 不会将内联汇编 "=g"输出优化为内存操作数?

改变宇宙飞船运动的 assembly 指令(DEC 至 MOV)

位掩码的 C++ 面向对象等价物

c++ - 在 C++ 程序中使用 _asm 代码是否有所不同

assembly - i386 指令 "div ah"毫无意义吗?

c - 与位置无关的代码差异 : x86 vs x86-64