是否有一个地方在libc函数FMA可以使用任何场景?(Is there any scenario w

2019-07-03 15:57发布

我碰到过这个网页 ,发现有一个奇怪的浮动乘加功能- fmafmaf 。 它说,结果是这样的:

 (x * y) + z             #fma(x,y,z)

和值是无限的精度,圆一次结果的格式

然而,AFAICT我以前从来没有见过这样的三元操作。 所以我想知道什么是这个FUNC的cumstom使用。

Answer 1:

融合乘法 - 加法指令的重要方面是中间结果的(几乎)无限精度。 这有助于性能,但没有这么多,因为两个操作在一个指令编码-它有助于性能,因为中间结果的几乎无限精度有时是非常重要的, 很贵的普通乘法和加法恢复时,这个级别的精度是真正的程序员是什么之后。

实施例:比较a * b1.0

假设它是一个算法的关键,以确定其中的两个双精度数的产品ab是相对于一个非零常数(我们将使用1.0 )。 这些数字ab都有的二进制数字完全有效数。 如果计算a*bdouble ,结果可能是1.0 ,但是这并不能告诉你实际的数学产品是否略低于1.0,四舍五入精确1.0,或略高于1.0和四舍五入。 没有FMA,你的选择是:

  1. 计算a*b作为四精度数。 四精度不会在硬件中实现,但也有软件仿真库。 在四精度,产品的数学结果是精确表示的,然后你可以把它比作1.0。

  2. 计算a*b在双精度在圆向上模式和圆向下模式。 如果这两个结果是1.0,这意味着a*b正好是1.0。 如果RU(A * B)大于1.0,则意味着数学乘积是高于1.0,并且如果RD(A * B)低于1.0,这意味着数学乘积低于1.0。 在大多数处理器上,这种方式意味着要改变舍入模式三次,每变化是昂贵的(它涉及冲洗CPU流水线)。

用FMA指令,可以计算fma(a, b, -1.0)和比较的结果为0.0。 由于浮点数是零附近较密,并且由于中间产物未在计算圆形的,我们可以肯定的是fma(a, b, -1.0) > 0表示的数学乘积ab是大于1 , 等等。

例如:Veltkamp /德克尔乘法

该两双格式是数字的有效的表示为两个双精度浮点数的总和。 它几乎是为四精度精确,但利用现有的双精度硬件。

考虑下面的函数, Mul12(a, b)即需要两个双精度数ab ,并计算它们的产物,为两双数。 的算法,由于Veltkamp和德克尔,计算仅具有双精度加法和乘法(该功能参考 )。 需要6次乘法(一个是每个的一部分Split()加四在该算法的主体),和大量的加法。

如果FMA指令是可用的, Mul12可以实现为两个业务,一个乘法和一个FMA。

high = a * b; /* double-precision approximation of the real product */
low = fma(a, b, -high); /* remainder of the real product */
/* now the real product of a and b is available as the sum of high and low */

更多示例

其中FMA用于其精度,和实施例不仅如,做了乘法和加法的指令,是平方根和除法的计算。 这些操作具有根据IEEE 754标准被正确地舍入(以数学结果的最近浮点数)。 这两种操作可以有效地在硬件FMA指令可实现。 这个方面通常由编译链隐藏,但在IA-64指令集(安腾)没有用于除法的指令。 取而代之的是,正确地舍入除法可通过指令涉及FMA的序列(一般由编译器产生的)而得到。



Answer 2:

它通常用作优化。 最浮点单元有一个fma指令,所以计算可以在单个指令中,而不是两个或更多个来执行。 因此,对于性能要求较高的浮点代码,这是一个有用的功能有。



文章来源: Is there any scenario where function fma in libc can be used?