10

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

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

我想将其替换为:

vfmadd231sd %xmm0, %xmm1, %xmm2

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

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

4

1 回答 1

17

不。事实上,融合乘加的主要好处是它不会(必然)产生与单独的乘加相同的结果。

作为一个(有些人为的)示例,假设我们有:

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.

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

于 2015-03-16T20:36:03.233 回答