繁体   English   中英

为什么 x86_64 CPU 上的通用寄存器没有融合乘加?

[英]Why is there no fused multiply-add for general-purpose registers on x86_64 CPUs?

在 Intel 和 AMD x86_64 处理器上,SIMD 矢量化寄存器具有特定的融合乘加功能,但通用(标量、整数)寄存器没有- 你基本上需要先乘,然后加(除非你可以将东西放入lea ).

这是为什么? 我的意思是,它是否无用以至于不值得开销?

整数乘法很常见,但不是常见的整数乘法之一。 但是对于浮点数,一直使用乘法和加法,并且 FMA 为许多 ALU 绑定的 FP 代码提供了主要的加速。

此外,浮点数实际上避免了 FMA 的精度损失( x*y内部临时变量在添加之前根本没有四舍五入)。 这就是存在 ISO C99 / C++ fma()数学库函数的原因,以及为什么在没有硬件 FMA 支持的情况下实现起来很慢的原因。

整数 FMA(或乘法累加,又名 MAC)与单独的乘法和加法相比没有任何精度优势。


一些非 x86 ISA 确实提供整数 FMA。 它并非毫无用处,但英特尔和 AMD 直到 AVX512-IFMA都没有费心将它包括在内(而且这仍然仅适用于 SIMD,基本上公开了双精度 FMA/ vmulpd所需的 52 位尾数乘法器电路以供整数指令使用).

非 x86 示例包括:

  • MIPS32madd / maddu (无符号)乘法累加到hi / lo寄存器(常规乘法和除法指令用作目标的特殊寄存器)。

  • ARM smlal和朋友(32x32=>64 位 MAC,或 16x16=>32 位),也可用于无符号整数。 操作数是常规的 R0..R15 通用寄存器。


整数寄存器 FMA 在 x86 上很有用,但具有 3 个整数输入的 uops 很少见 CMOV 和 ADC 有 3 个输入,但其中一个是标志。 即便如此,在为 Haswell 的 FP FMA 添加了 3 输入微指令支持之后,直到 Broadwell,他们才在 Intel 上解码为单个微指令。

Haswell 及更高版本可以跟踪具有 3 个整数输入的融合域微指令,不过, 对于具有索引寻址模式的(某些)微融合指令 Sandybridge/Ivybridge un-laminate 指令,如add eax, [rdx+rcx] (但 Nehalem 可以让它们保持微融合,就像 Haswell 一样;SnB 简化了融合域 uop 格式)。 无论如何,那是融合域,不在调度程序中。 只有 Broadwell/Skylake 可以在调度程序中跟踪 3 输入整数 uops,并且仅适用于 2 个整数 + 标志,而不是 3 个整数寄存器。

英特尔确实使用了“统一”调度器,其中 FP 和整数运算使用相同的调度器,并且它可以跟踪适当的 3 输入 FP FMA。 如果存在技术障碍,那么 IDK。 如果不是,IDK 为什么英特尔没有将整数 FMA 作为 BMI2 的一部分或其他东西,它添加了诸如mulx的东西(2 输入 2 输出mul ,主要是显式操作数,与使用rdx:rax的传统mul不同。)


SSE2/SSSE3确实有用于向量寄存器的整数乘加指令,但只有在加宽 16x16 => 32 位 ( SSE2 pmaddwd ) 或 (unsigned)8x(signed)8=>16 位 ( SSSE3 pmaddubsw ) 后才可以进行水平加法。

但这些只是 2 输入指令,所以即使有乘法和加法,它也与 FMA 有很大不同。


脚注:问题标题最初说没有“用于标量”的 FMA。 标量 FP FMA 具有相同的 FMA3 扩展,添加了这些的打包版本: VFMADD231SD和朋友在标量双精度上运行,并且 vfmaddXXXss 的相同风格可用于 XMM 寄存器中的标量浮点数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM