做 FMA(融合乘加)指令总是产生与 mul 然后添加指令相同的结果



我有这个程序集(AT&T语法):

mulsd   %xmm0, %xmm1
addsd   %xmm1, %xmm2

我想用以下方式替换它:

vfmadd231sd %xmm0, %xmm1, %xmm2

这种转换是否总是在所有涉及的寄存器和标志中留下等效的状态?还是结果浮动会在某些方面略有不同?(如果它们不同,为什么会这样?

(关于FMA说明:http://en.wikipedia.org/wiki/FMA_instruction_set)

No. 事实上,融合乘加法的一个主要好处是,它(不一定)不会产生与单独的乘法和加法相同的结果。

作为一个(有点做作的)例子,假设我们有:

double a = 1 + 0x1.0p-52 // 1 + 2**-52
double b = 1 - 0x1.0p-52 // 1 - 2**-52

我们想计算a*b - 1. a*b - 1的"数学精确"值为:

(1 + 2**-52)(1 - 2**-52) - 1 = 1 + 2**-52 - 2**52 - 2**-104 - 1 = -2**-104

但是,如果我们首先使用乘法计算a*b,它会四舍五入为 1.0,因此随后的 1.0 减法会产生零的结果。

如果我们改用fma(a,b,-1),我们消除了产品的中间四舍五入,这使我们能够得到"真实"的答案,-1.0p-104 .

请注意,我们不仅得到不同的结果,而且还设置了不同的标志;单独的乘减设置不精确的标志,而融合的乘加不设置任何标志。

相关内容

  • 没有找到相关文章

最新更新