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
是同一个寄存器吗?
2条答案
按热度按时间z9zf31ra1#
xmm0
是ymm0
的下半部分,就像eax
是rax
的下半部分一样。写入
xmm0
(使用像vaddps xmm
这样的VEX编码指令,而不是传统SSEaddps xmm
)会将ymm0
、just like writing toeax
zeros the upper half ofrax
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位版本仅在AVX 2中可用,AVX仅提供128位版本。有几个例外,如AVX 1中的vptest ymm, ymm
。和vmovdqu
,如果您将其视为“整数”指令)。标量指令,如
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
的目标寄存器会改变含义,所以为了一致性,最好不要这样做)。brgchamk2#
根据维基百科,在AVX中:
YMM
寄存器的长度为256位。XMM
寄存器的长度为128位,表示YMM
寄存器的低128位**。YMM
和XMM
寄存器重叠,XMM
包含在YMM
中。图自wikimedia: