作者:桃花源主ITXB | 来源:互联网 | 2022-12-24 16:16
在Intel和AMD x86_64处理器上,SIMD矢量化寄存器具有特定的融合乘法 - 加法功能,但通用(标量,整数)寄存器不具备 - 您基本上需要相乘,然后添加(除非您可以适应lea
) .
这是为什么?我的意思是,它是否无用,以至于不值得开销?
1> Peter Cordes..:
整数乘法很常见,但不是整数最常见的事情之一.但是对于浮点数,总是使用乘法和加法,并且FMA 为许多ALU绑定的FP代码提供了主要的加速.
此外,浮点实际上避免了使用FMA的精度损失(x*y
内部临时在添加之前根本没有舍入).这就是ISO C99/C++ fma()
数学库函数存在的原因,以及为什么在没有硬件FMA支持的情况下实现它的速度很慢.
整数FMA(或乘法累加,又称MAC)与单独的乘法和加法相比没有任何精确的好处.
一些非x86 ISA确实提供整数FMA.它并没有用,但英特尔和AMD都没有费心将它包括在AVX512-IFMA之前(这仍然仅用于SIMD,基本上暴露了双精度FMA/vmulpd
整数指令使用所需的52位尾数乘法器电路) .
非x86示例包括:
MIPS32,madd
/ maddu
(无符号)乘法累加到hi
/ lo
寄存器(通过常规乘法和除法指令用作目的地的特殊寄存器).
ARMsmlal
和朋友(32x32 => 64位MAC,或16x16 => 32位),也可用于无符号整数.操作数是常规的R0..R15通用寄存器.
整数寄存器FMA在x86上很有用,但是具有3个整数输入的uops很少见.CMOV和ADC有3个输入,但其中一个是标志.即便如此,在Haswell为FP FMA添加了3输入uop支持之后,他们还是没有解码到Intel上的单个uop.
Haswell和后来可以跟踪带有3个整数输入的融合域uop,用于(某些)具有索引寻址模式的微融合指令.Sandybridge/Ivybridge非层压指令如add eax, [rdx+rcx]
.(但Nehalem可以让它们像Haswell一样保持微融合; SnB简化了融合域uop格式).无论如何,这是融合域,而不是调度程序.只有Broadwell/Skylake可以在调度程序中跟踪3输入整数uop,这仅适用于2个整数+标志,而不是3个整数寄存器.
英特尔确实使用"统一"调度程序,其中FP和整数运算使用相同的调度程序,并且它可以跟踪正确的3输入FP FMA.IDK是否存在技术障碍.如果没有,IDK为什么英特尔不包括整数FMA作为BMI2的一部分或其他东西,它增加了诸如mulx
(2输入2输出mul
,主要是显式操作数,与mul
使用的遗产不同rdx:rax
).
SSE2/SSSE3 确实有向量寄存器的整数mul-add指令,但只有在加宽16x16 => 32位(SSE2pmaddwd
)或(无符号)8x(有符号)8 => 16位(SSSE3pmaddubsw
)后才进行水平加法.
但这些只是2输入指令,所以尽管有乘法和加法,但它与FMA非常不同.
脚注:问题标题最初表示没有FMA"for scalars".标量FP FMA具有相同的FMA3扩展,添加了这些的打包版本: VFMADD231SD
并且朋友以标量双精度操作,并且相同风格的vfmaddXXXss可用于XMM寄存器中的标量浮点数.