首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在libc中是否可以使用函数fma?

在libc中是否可以使用函数fma?
EN

Stack Overflow用户
提问于 2012-11-08 15:24:43
回答 2查看 990关注 0票数 5

我遇到了此页,发现有一个奇怪的浮动乘积加法函数--fmafmaf。它说结果是这样的:

代码语言:javascript
运行
复制
 (x * y) + z             #fma(x,y,z)

该值对结果格式具有无限精度和一次圆的特点。

然而,AFAICT,我从来没有见过这样的三元操作。所以我想知道这个功能的习惯用法是什么。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-14 18:44:22

融合乘法加指令的重要方面是中间结果的(实质上)无限精度。这有助于提高性能,但这并不是因为两个操作是在一条指令中编码的--这有助于性能,因为中间结果的几乎无限精度有时很重要,当程序员真正追求这种精度时,用普通乘法和加法恢复非常昂贵。

示例:将a * b1.0进行比较

假设对于确定两个双精度数字ab的乘积相对于一个非零常数(我们将使用1.0)的算法是至关重要的。数字ab都有完全有意义的二进制数字。如果将a*b计算为一个double,结果可能是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/Dekker乘法

双倍格式是一种将数字表示为两个双精度浮点数之和的有效方法.它几乎和四精度一样精确,但利用了现有的双精度硬件.

考虑以下函数Mul12(a, b),它接受两个双精度数字ab,并将它们的乘积计算为双倍数字。由于Veltkamp和Dekker算法,仅用双精度加法和乘法(参考文献)计算这个函数.它需要6个乘法(一个是每个Split()的一部分,加上算法主体中的四个),还有大量的加法。

如果一个FMA指令可用,Mul12可以实现为两个操作,一个乘法和一个FMA。

代码语言:javascript
运行
复制
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的一系列指令(通常由编译器生成)获得正确的四舍五入。

票数 17
EN

Stack Overflow用户

发布于 2012-11-08 15:27:29

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13292013

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档