英特尔 AVX-512:如何设置 EVEX.z 位

Intel AVX-512: how to set the EVEX.z bit

EVEX.z 位在 AVX-512 中与 k 寄存器一起用于控制屏蔽。如果 z 位为 0,则为合并屏蔽;如果 z 位为 1,则 k 寄存器中的零元素在输出中归零。

语法如下所示:

VPSUBQ zmm0{k2}{z},zmm1,zmm2

其中 {z} 代表 z 位。

但是如何设置或测试 EVEX.z 位?我搜索了所有我能找到的资源,但没有找到答案。

据我了解,他们的意思是VPSUBQ zmm0{k2}{z},zmm1,zmm2
VPSUBQ zmm0{k2},zmm1,zmm2是两条不同的指令,其编码只有一个位不同,称为"z bit"。 (它特别是指令的 EVEX 前缀的一部分。Wikipedia documents 所有字段)

因此,您 "set the z bit" 通过在您的汇编程序源代码中指定 {z},告诉汇编程序生成一条具有相应位集的指令。这在很多地方都有记录,比如英特尔的第 2 卷指令集手册,以及英特尔的 intrinsics guide with mask (merge-masking) vs. maskz (zero-masking) versions of most intrinsics)

不是处​​于CPU状态的物理位,例如方向标志或其他东西,它会从一条指令持续到下一条指令。 "test" 没有意义。


为了说明,这是我通过组装两个版本得到的结果:

00000000  62F1F5CAFBC2      vpsubq zmm0{k2}{z},zmm1,zmm2
00000006  62F1F54AFBC2      vpsubq zmm0{k2},zmm1,zmm2

请注意,编码在第四个字节的高位有所不同。那是你的 "z bit".


也许你在想可以在运行时"set"或"clear"z位,从而改变后续指令的屏蔽效果?由于它是每条指令编码的一部分,而不是 CPU 状态,因此这种思维方式仅在您即时 JIT 指令或使用自修改代码时才有效。

在 "normal" 提前代码中,您必须在两个版本中编写代码,一次使用 {z} 指令,一次不使用。使用条件跳转来决定执行哪个版本。