C-是否可以使用LIBC中的功能FMA的任何情况



我遇到此页面,发现有一个奇数 floing乘乘添加函数- fmafmaf。它说结果是:

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

和该值为无限的精度,然后将其圆形为结果格式

但是,我以前从未见过这样的三元操作。因此,我想知道此功能的混乱用法是什么。

融合 - 添加指令的重要方面是中间结果的(实际上)无限精度。这有助于表现,但没有很多,因为两个操作是在单个指令中编码的 - 它有助于表现,因为中间结果的几乎无限精度有时很重要,非常与普通恢复的昂贵当该精确度是程序员之后的乘法和添加。

示例:将a * b1.0

进行比较

假设对算法至关重要,以确定两个双重精度 ab的乘积相对于非零常数(我们将使用1.0)。ab的数字都具有完整的二进制数字。如果将a*b计算为double,则结果可能为1.0,但这并不能告诉您实际的数学产品是否略低于1.0,恰好达到1.0,还是略高于1.0,或者略高于1.0并舍入。没有FMA,您的选择是:

  1. a*b计算为Quad-Precision编号。硬件中未实现Quad Precision,但有软件仿真库。在Quad-Precision中,产品的数学结果是完全表示的,然后您可以将其与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/Dekker乘法

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

考虑以下功能Mul12(a, b),该功能采用两个双精度数字ab,并将其产品计算为双双数字。由于Veltkamp和Dekker,一种算法仅通过双重添加和乘法(参考)来计算此功能。它需要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指令集(ITANIUM)没有分裂的说明。取而代之的是,可以通过涉及FMA的一系列指令(通常由编译器生成)获得正确的圆形划分。

通常用作优化。大多数浮点单元具有fma指令,因此可以在单个指令中而不是两个或更多指令中执行计算。因此,对于关键绩效浮点代码,它具有有用的功能。

相关内容

  • 没有找到相关文章

最新更新