Intel AVX-512:如何设置 EVEX.z 位

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

提问人:RTC222 提问时间:3/21/2020 最后编辑:Peter CordesRTC222 更新时间:3/21/2020 访问量:504

问:

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

语法如下所示:

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

其中 {z} 表示 z 位。

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

程序集 x86 机器代码 AVX512

评论

1赞 Nate Eldredge 3/21/2020
我认为这是操作码的一部分,而不是 CPU 状态的一部分。
0赞 RTC222 3/21/2020
这是否意味着我无法设置它——换句话说,如果我执行上面显示的 VPSUBQ 指令,z 位就没有灵活性?
0赞 fuz 3/21/2020
这是正确的。z 位将始终按照指令中指定的方式进行设置。

答:

6赞 Nate Eldredge 3/21/2020 #1

据我了解,它们的意思是 和
是两个不同的指令,它们的编码在一位上有所不同,称为“z 位”。(它是指令的 EVEX 前缀的特定部分。维基百科记录了所有字段)
VPSUBQ zmm0{k2}{z},zmm1,zmm2VPSUBQ zmm0{k2},zmm1,zmm2

因此,您可以通过在汇编器源代码中指定来“设置 z 位”,告诉汇编器生成设置了相应位的指令。这在很多地方都有记录,比如英特尔的 vol.2 指令集手册,以及英特尔的内部函数指南中,其中有掩码(合并掩码)与大多数内部函数的掩码(零掩码)版本){z}

它不是 CPU 状态下的物理位,如方向标志或其他东西,它会从一条指令持续到下一条指令。“测试”它是没有意义的。


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

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

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


也许你认为你可以在运行时“设置”或“清除”z位,从而改变后续指令的屏蔽效果?由于它是每条指令编码的一部分,而不是 CPU 状态的一部分,因此这种思维方式仅在动态 JIT 处理指令或使用自修改代码时才有效。

在“正常”的预置代码中,您必须在两个版本中编写代码,一次带有指令,一次没有指令。使用条件跳转来决定要执行的版本。{z}

评论

1赞 RTC222 3/21/2020
我们不应该对 SO 说谢谢,但你的回答扩展了知识库,因为这是我所知道的关于它是如何设置的唯一解释。所以谢谢。
1赞 Peter Cordes 3/21/2020
@RTC222:AVX512 EVEX 前缀编码/位完整记录在英特尔的 vol.2 手册中。能够使用合并掩码与零掩码(和舍入模式覆盖)在很多地方都有提及,包括英特尔的内部函数指南。(尽管该指南的 ASM 语法示例只是使用 而不是 ,这很奇怪,即使它记录的是内部函数而不是 asm。无论如何,这个答案很好地将各个部分放在一起。{z}{k1}{z}
0赞 RTC222 3/21/2020
我在 2019 年 10 月合并卷第 15.1.4 卷第 1 节和第 2A 卷第 3.1.1.3 节中找到了口头描述,但都没有解释您没有设置 z 位,而是在需要时将其从指令中删除。内特·埃尔德雷奇(Nate Eldredge)的回答很好地澄清了这一点。
0赞 vitsoft 3/21/2020
英特尔提出并由 NASM 维护的装饰器语法记录不足。它没有指定装饰器是否不区分大小写 {Z},它们是否可以交换 {z}{k2},它们可以放在操作数列表中的确切位置......这就是为什么其他汇编程序使用替代语法的原因:euroassembler.eu/eadoc/#ZEROINGeq