ASM x86_64 AVX:xmm 和 ymm 寄存器差异

Posted

技术标签:

【中文标题】ASM x86_64 AVX:xmm 和 ymm 寄存器差异【英文标题】:ASM x86_64 AVX: xmm and ymm registers differences 【发布时间】:2018-06-16 19:05:24 【问题描述】:

xmmymm 寄存器有什么区别? 我以为xmm是SSE的,ymm是AVX的,但我写了一些代码:

vmovups     ymm1, [r9]      
vcvtss2si   rcx, ymm1

它给了我:

error: invalid combination of opcode and operands

这是关于行的:

vcvtss2si   rcx, ymm1

所以我写了:

vcvtss2si   rcx, xmm1

它按预期工作。 ymm1 向量的第一个值,转换为整数,现在位于rcx

这到底是怎么回事? ymm1xmm1 是同一个寄存器吗?

【问题讨论】:

xmm1ymm1(以及其他索引)之间的主要区别在于前者的长度为 128 位,而后者的长度为 256。 那么xmm1' and ymm1`共享同一个内存?如果我想使用仅使用前 128 位的指令,使用 xmmymm 没关系?或者可能每条仅使用前 128 位的指令都需要使用 xmm 好的,所以我从内存中处理 256 位数据:vmovups ymm1, [r9] 然后我转换xmm1 的第一个元素(不是ymm1)并将其保存在rcx 中: vcvtss2si rcx, xmm1 怎么可能在rcx 中是ymm1 的第一个值?它不应该是来自xmm1 的“随机”数字吗?如果xmm1ymm1是独立的寄存器,为什么ymm1xmm1的第一个元素是一样的? 感谢您的链接。我现在明白我错了。你是对的,两个寄存器的低 128 位是通用的。请忽略我之前的评论。 @LeandroCaniglia:您可以(并且应该)删除不正确的 cmets。 xmm0ymm0 的下半部分,就像eaxrax 的下半部分一样。 (写xmm0ymm0 的上车道归零) 【参考方案1】:

xmm0ymm0 的下半部分,就像eaxrax 的下半部分一样。

写入xmm0(使用 VEX 编码指令,而不是旧版 SSE)将 ymm0、just like writing to eax zeros the upper half of rax to avoid false dependencies 的上部通道归零。旧版 SSE 指令没有将高字节归零是为什么会有 penalty for mixing AVX and legacy SSE instructions。

大多数 AVX 指令都有 128 位或 256 位大小。例如vaddps xmm0, xmm1, xmm2vaddps ymm0, ymm1, ymm2。 (大多数整数指令的 256 位版本仅在 AVX2 中可用,而 AVX 仅提供 128 位版本。有几个例外,例如 AVX1 中的 vptest ymm, ymm。如果您将其视为“整数”指令)。

vmovdvcvtss2sivcvtsi2ss 等标量指令仅适用于 XMM 寄存器。读取 YMM 寄存器与读取 XMM 寄存器在逻辑上没有区别,但是 写入 低元素(并且不修改其他元素,就像设计不佳的 vcvtsi2ss 所做的那样)对于 XMM 和. YMM,因为 YMM 版本会使上车道不归零。


但是机器码编码中不存在带有 ymm 的标量,即使对于像 vpinsrd / vpextrd (插入/提取标量)这样真正有用的指令也是如此。

请注意,即使读取 XMM 寄存器并仅获取低标量元素在逻辑上与 YMM 相同,但对于实际实现,它不会相同。读取 YMM 寄存器意味着 AVX-256 指令,该指令必须将 CPU 从“已保存的上”状态转换(对于具有 SSE/AVX 转换/状态的 Intel CPU)。

在任何情况下,vcvtss2si rax, ymm0 是不可编码的,并且汇编器不会神奇地将其组装为vcvtss2si rax, xmm0。如果你用 asm 编写,你应该确切地知道你在做什么。 (虽然一些汇编程序会为您优化mov rax, 1mov eax, 1,所以让您将ymm 作为源寄存器写是可行的。但是让您将ymm 作为vcvtsi2ss 的目标寄存器写会改变意思,所以为了保持一致性,最好不要这样做)。

【讨论】:

【参考方案2】:

根据wikipedia,在 AVX 中:

YMM 寄存器的长度为 256 位

XMM 寄存器的长度为 128 位,代表YMM 寄存器的低 128 位

YMMXMM 寄存器重叠,XMM 包含在 YMM 中。

来自wikimedia的图:

【讨论】:

以上是关于ASM x86_64 AVX:xmm 和 ymm 寄存器差异的主要内容,如果未能解决你的问题,请参考以下文章

测试 256 位 YMM AVX 寄存器为零的最有效/惯用方法

使用 x64 SSE / AVX 寄存器进行字符串反转

将有效地址加载到 x86_64 中的 XMM 寄存器的一条指令?

在 x86_64 汇编问题中添加双精度

AVX2 1x mm256i 32bit 到 2x mm256i 64bit

什么决定CPU寄存器和总线的数据宽度