1

在 FMA(3) 的 BSD 库函数手册中,它说“这些函数计算 x * y + z”。

那么 FMA 和执行 x * y + z 的简单代码有什么区别?以及为什么 FMA 在大多数情况下都有更好的性能?

4

2 回答 2

3

[我没有足够的业力发表评论;添加另一个答案似乎是唯一的可能性。]

埃里克的回答很好地涵盖了一切,但需要注意的是:有时使用fma(a, b, c)代替a*b+c可能会导致难以诊断的问题。

考虑

x = sqrt(a*a - b*b);

如果换成

x = sqrt(fma(a, a, -b*b));

a和的值,函数b的参数sqrt可能为负,即使|a|>=|b|. 特别是,如果|a|=|b|和 无限精确乘积a*a小于 的四舍五入值,则会发生这种情况a*a。这是因为计算中的舍入误差a*a由 给出fma(a, a, -a*a)

于 2019-08-22T20:25:04.590 回答
2

a*b+c产生一个结果,就好像计算是:

  • 计算 和 的无限精确a乘积b
  • 将该产品四舍五入为正在使用的浮点格式。
  • 计算该结果 和 的无限精确总和c
  • 将该总和四舍五入到正在使用的浮点格式。

fma(a, b, c)产生一个结果,就好像计算是:

  • 计算 和 的无限精确a乘积b
  • 计算该乘积 和 的无限精确和c
  • 将该总和四舍五入到正在使用的浮点格式。

所以它跳过了将中间产品四舍五入为浮点格式的步骤。

在具有 FMA 指令的处理器上,融合乘加可能更快,因为它是一条浮点指令而不是两条,并且硬件工程师通常可以设计处理器以高效地执行此操作。在没有 FMA 指令的处理器上,融合乘加可能会更慢,因为软件必须使用额外的指令来维护获得所需结果所需的信息。

于 2019-08-22T02:28:48.323 回答