Assembly 为什么FMA“U mm256”fmadd“U pd()内在函数有3个asm助记符?”;vfmadd132pd“的&引用;231“;及;213“吗;?

Assembly 为什么FMA“U mm256”fmadd“U pd()内在函数有3个asm助记符?”;vfmadd132pd“的&引用;231“;及;213“吗;?,assembly,x86,simd,instruction-set,fma,Assembly,X86,Simd,Instruction Set,Fma,有人能给我解释一下为什么融合乘法累加指令有三种变体:vfmad132pd、vfmad231pd和vfmad213pd,而只有一个C内部函数\u mm256\u fmadd\u pd 简单地说,两者之间有什么区别(在AT&T语法中) 我没有从他那里得到任何消息。我这样问是因为我在我编写的一段C代码的汇编程序输出中看到了所有这些。谢谢 一个干净的答案(重新格式化下面的答案) 对于变体ijk,vfmadijkpd的含义: 英特尔语法:op(i)*op(j)+op(k)->op(1) AT&T语法:

有人能给我解释一下为什么融合乘法累加指令有三种变体:
vfmad132pd
vfmad231pd
vfmad213pd
,而只有一个C内部函数
\u mm256\u fmadd\u pd

简单地说,两者之间有什么区别(在AT&T语法中)

我没有从他那里得到任何消息。我这样问是因为我在我编写的一段C代码的汇编程序输出中看到了所有这些。谢谢


一个干净的答案(重新格式化下面的答案)

对于变体
ijk
vfmadijkpd
的含义:

  • 英特尔语法:
    op(i)*op(j)+op(k)->op(1)
  • AT&T语法:
    op(4-i)*op(4-j)+op(4-k)->op(3)
其中,
op(n)
表示指令后的第n个操作数。因此,在这两者之间存在一个反向变换:

n <- 4 - n
n这在程序集中,也在它的HTML摘录中,如以下条目:

VFMADD132PD:乘以两个或四个压缩双精度 从第一个源操作数到两个或多个操作数的浮点值 第三个源中的四个压缩双精度浮点值 操作数,将无限精度中间结果与两个 或第二个压缩双精度浮点值 源操作数,执行舍入并存储结果2或4 将双精度浮点值压缩到目标 操作数(第一个源操作数)

VFMADD213PD:将二者相乘或 来自秒的四个压缩双精度浮点值 源操作数到两个或四个压缩双精度 第一个源操作数中的浮点值与无穷大值相加 将中间结果精确到两个或四个压缩 第三个源操作数中的双精度浮点值, 执行舍入并存储生成的两个或四个数据 目标操作数的双精度浮点值 (第一个源操作数)

VFMADD231PD:乘以两个或四个压缩 从第二个源到 第三个中的两个或四个压缩双精度浮点值 源操作数,将无限精度中间结果添加到 中的两个或四个压缩双精度浮点值 第一个源操作数,执行舍入并存储结果两个 或将四个压缩双精度浮点值发送到desti- 国家操作数(第一个源操作数)


融合的乘法-加法指令将两个(压缩)值相乘,再加上第三个值,然后用结果覆盖其中一个值。三个值中只有一个可以是内存操作数,而不是寄存器

它的工作方式是所有三条指令都覆盖
ymm0
,只允许
ymm2
作为内存操作数。指令的选择决定了哪两个操作数相乘,哪两个操作数相加

假设ymm0是英特尔语法中的第一个操作数(或AT&T语法中的最后一个操作数):


当使用C intrinsic时,这个选择是不必要的:intrinsic不会覆盖一个值,而是返回它的结果,它允许从内存中读取所有三个值。如果需要,编译器将添加内存读/写,如果不想覆盖这三个值中的任何一个,编译器将分配一个临时寄存器来存储结果。它将根据需要从三条指令中选择一条。

@Alphabetagama是的,我使用了Intel语法,这也是您将发现的几乎所有指令集引用所使用的语法。AT&T语法的许多错误之一是,它切换操作数顺序以将目标放在末尾。对于这些指令,这也意味着指令名称中的
1
/
2
/
3
不再正确(在英特尔语法中,123表示指令执行1*2+3,其中1,2,3是操作数的顺序)。请注意,AVX和FMA是两个独立的东西-有些CPU有AVX,但没有FMA-您可能应该从标题和标签中删除AVX,以避免混淆。@Zboson:显然AMD有FMA3,但只有AVX(不是AVX2)。@PaulR,woah,我不知道。GCC给出这样的警告有点奇怪,因为它并非在所有情况下都是正确的。事实上,Steamroller也没有AVX2,但有FMA3。@Zboson的想法是,如果您要编译没有AVX2的FMA3,那么您应该编译FMA4。@PaulR:FMA3依赖于AVX,因为它使用VEX编码。我猜AVX标记仍然与指令命名无关。为什么第二条指令应用的模式是213而不是123?你能举一个简单的例子来解释这个区别吗?
n <- 4 - n
vfmadd132pd:  ymm0 = ymm0 * ymm2/mem + ymm1
vfmadd231pd:  ymm0 = ymm1 * ymm2/mem + ymm0
vfmadd213pd:  ymm0 = ymm1 * ymm0 + ymm2/mem