4

在查看这段代码时,我注意到以下四个指令:

vmulpd  %ymm1,%ymm3,%ymm4 /* aim*bim */
vmulpd  %ymm0,%ymm3,%ymm6 /* are*bim */
vfmadd231pd %ymm2,%ymm1,%ymm6
vfmsub231pd %ymm0,%ymm2,%ymm4

现在,如果您认为 AT&T 表示法中的指令是 形式的operator source,source,destination,那么第一条指令不是没用吗?

%ymm4 = f(%ymm1, %ymm3)
%ymm6 = f(%ymm0, %ymm3)
%ymm6 = f(%ymm2, %ymm1)
%ymm4 = f(%ymm0, %ymm2)

前两个值显然从未读取过,因此不应计算它们。但是,似乎情况并非如此,因为如果我删除这些行,测试就会失败。

4

1 回答 1

7

FMA是3输入指令,计算a * b + c;目标是一个读写操作数(如 SSE2 mulpd %xmm0, %xmm1)。

FMADD/FMSUB/FNMADD/FNMSUB(甚至 FMADDSUB / FMSUBADD)指令都有 3 个操作数顺序,让您可以选择 3 个操作数(a、b 或 c)中的哪一个是读写目标操作数,并且哪个可以是内存操作数。请参阅/ /的文档vfmadd231pd132PD213PD以查看哪些输入被相乘,哪些是代码中的“累加器”。(我永远无法将编号方案直接记在脑海中:这是使用内在函数编写要容易得多的一种情况。但目的地始终是最后的。)

请注意,英特尔文档使用英特尔语法,dst, src1, src2, .... 反转操作数列表以获得 AT&T 语法,例如..., src2, src1, dst. 请参阅at&t-syntax 标签 wikiintel-syntax 标签 wiki


顺便说一句,有一个 FMA4 ISA 扩展,其中 FMA 指令有 3 个输入和一个单独的输出。请参阅https://en.wikipedia.org/wiki/FMA_instruction_set

Intel 原本打算实现 FMA4,但后来改为现在的 FMA3(直到尽可能晚才告诉 AMD,出于反竞争的原因:参见 Agner Fog 的博文Stop the instruction set war)。对于AMD Bulldozer,来不及改变,所以Bulldozer只支持FMA4。打桩机支持 FMA3 和 FMA4。在 Zen 2 之前,Ryzen 非正式地支持两者。英特尔 CPU 只支持 FMA3。

Ryzen Zen1 / Zen+ 芯片显然可以正确解码和执行 FMA4 指令,但未在 CPUID 中报告 FMA4 支持。(有一份关于错误 FMA4 结果的粗略报告,但没有其他人复制它。似乎只是根据该报告流传的 FUD 谣言,可能是软件错误而不是芯片问题。)

但是,Zen 2 不支持FMA4;非法指令 ( #UD) 异常。

于 2017-12-10T14:22:05.737 回答