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 【问题描述】:xmm
和 ymm
寄存器有什么区别?
我以为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
。
这到底是怎么回事? ymm1
和 xmm1
是同一个寄存器吗?
【问题讨论】:
xmm1
和ymm1
(以及其他索引)之间的主要区别在于前者的长度为 128 位,而后者的长度为 256。
那么xmm1' and
ymm1`共享同一个内存?如果我想使用仅使用前 128 位的指令,使用 xmm
或 ymm
没关系?或者可能每条仅使用前 128 位的指令都需要使用 xmm
?
好的,所以我从内存中处理 256 位数据:vmovups ymm1, [r9]
然后我转换xmm1
的第一个元素(不是ymm1
)并将其保存在rcx
中: vcvtss2si rcx, xmm1
怎么可能在rcx
中是ymm1
的第一个值?它不应该是来自xmm1
的“随机”数字吗?如果xmm1
和ymm1
是独立的寄存器,为什么ymm1
和xmm1
的第一个元素是一样的?
感谢您的链接。我现在明白我错了。你是对的,两个寄存器的低 128 位是通用的。请忽略我之前的评论。
@LeandroCaniglia:您可以(并且应该)删除不正确的 cmets。 xmm0
是ymm0
的下半部分,就像eax
是rax
的下半部分一样。 (写xmm0
将ymm0
的上车道归零)
【参考方案1】:
xmm0
是ymm0
的下半部分,就像eax
是rax
的下半部分一样。
写入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, xmm2
或 vaddps ymm0, ymm1, ymm2
。 (大多数整数指令的 256 位版本仅在 AVX2 中可用,而 AVX 仅提供 128 位版本。有几个例外,例如 AVX1 中的 vptest ymm, ymm
。如果您将其视为“整数”指令)。
vmovd
、vcvtss2si
和 vcvtsi2ss
等标量指令仅适用于 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, 1
到mov eax, 1
,所以让您将ymm
作为源寄存器写是可行的。但是让您将ymm
作为vcvtsi2ss
的目标寄存器写会改变意思,所以为了保持一致性,最好不要这样做)。
【讨论】:
【参考方案2】:根据wikipedia,在 AVX 中:
YMM
寄存器的长度为 256 位。
XMM
寄存器的长度为 128 位,代表YMM
寄存器的低 128 位。
YMM
和 XMM
寄存器重叠,XMM
包含在 YMM
中。
来自wikimedia的图:
【讨论】:
以上是关于ASM x86_64 AVX:xmm 和 ymm 寄存器差异的主要内容,如果未能解决你的问题,请参考以下文章
测试 256 位 YMM AVX 寄存器为零的最有效/惯用方法
将有效地址加载到 x86_64 中的 XMM 寄存器的一条指令?