我碰到过这个网页 ,发现有一个奇怪的浮动乘加功能- fma
和fmaf
。 它说,结果是这样的:
(x * y) + z #fma(x,y,z)
和值是无限的精度,圆一次结果的格式 。
然而,AFAICT我以前从来没有见过这样的三元操作。 所以我想知道什么是这个FUNC的cumstom使用。
我碰到过这个网页 ,发现有一个奇怪的浮动乘加功能- fma
和fmaf
。 它说,结果是这样的:
(x * y) + z #fma(x,y,z)
和值是无限的精度,圆一次结果的格式 。
然而,AFAICT我以前从来没有见过这样的三元操作。 所以我想知道什么是这个FUNC的cumstom使用。
融合乘法 - 加法指令的重要方面是中间结果的(几乎)无限精度。 这有助于性能,但没有这么多,因为两个操作在一个指令编码-它有助于性能,因为中间结果的几乎无限精度有时是非常重要的, 很贵的普通乘法和加法恢复时,这个级别的精度是真正的程序员是什么之后。
a * b
至1.0
假设它是一个算法的关键,以确定其中的两个双精度数的产品a
和b
是相对于一个非零常数(我们将使用1.0
)。 这些数字a
和b
都有的二进制数字完全有效数。 如果计算a*b
为double
,结果可能是1.0
,但是这并不能告诉你实际的数学产品是否略低于1.0,四舍五入精确1.0,或略高于1.0和四舍五入。 没有FMA,你的选择是:
计算a*b
作为四精度数。 四精度不会在硬件中实现,但也有软件仿真库。 在四精度,产品的数学结果是精确表示的,然后你可以把它比作1.0。
计算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
表示的数学乘积a
和b
是大于1 , 等等。
该两双格式是数字的有效的表示为两个双精度浮点数的总和。 它几乎是为四精度精确,但利用现有的双精度硬件。
考虑下面的函数, Mul12(a, b)
即需要两个双精度数a
和b
,并计算它们的产物,为两双数。 的算法,由于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的序列(一般由编译器产生的)而得到。
它通常用作优化。 最浮点单元有一个fma
指令,所以计算可以在单个指令中,而不是两个或更多个来执行。 因此,对于性能要求较高的浮点代码,这是一个有用的功能有。