Floating point 哪些算法从融合乘加中受益最大?

Floating point 哪些算法从融合乘加中受益最大?,floating-point,fma,Floating Point,Fma,fma(a,b,c)等同于a*b+c,只是它不舍入中间结果 你能给我一些算法的例子吗?这些算法从避免这种舍入中获益匪浅 这并不明显,因为我们避免的乘法之后的舍入比我们不避免的加法之后的舍入问题要小。在我的脑海中,矩阵乘法、牛顿法则、多项式求值、数值方法。FMA的主要好处是它可以快两倍。FPU可以在同一个周期内执行这两个操作,而不是先执行一个周期的乘法,然后执行一个周期的加法。显然,大多数算法将受益于更快的运算。一些示例:矢量点积。傅里叶变换。数字信号处理。多项式。各种各样的事情 这是一个优化和硬

fma(a,b,c)
等同于
a*b+c
,只是它不舍入中间结果

你能给我一些算法的例子吗?这些算法从避免这种舍入中获益匪浅


这并不明显,因为我们避免的乘法之后的舍入比我们不避免的加法之后的舍入问题要小。

在我的脑海中,矩阵乘法、牛顿法则、多项式求值、数值方法。

FMA的主要好处是它可以快两倍。FPU可以在同一个周期内执行这两个操作,而不是先执行一个周期的乘法,然后执行一个周期的加法。显然,大多数算法将受益于更快的运算。

一些示例:矢量点积。傅里叶变换。数字信号处理。多项式。各种各样的事情


这是一个优化和硬件开发的问题,而不是其他任何问题。乘积之和是数值方法中非常常见的要求,通过这种方式,您可以向编译器提供一条明确的指令,说明如何快速完成一件事情,并且可能更精确一点。除非我弄错了,否则编译器可以用FMA指令替换a=b*c+d,但也可以不替换。(除非标准要求四舍五入,但现实世界的编译器通常会在小范围内违反标准)。

到目前为止,我发现的唯一一件事是“无错误转换”。对于
a+b
a-b
a*b
中的任何浮点数错误,也都是浮点数(以舍入到最近的模式,假设没有溢出/下溢等)

加法(显然是减法)误差易于计算;如果
abs(a)>=abs(b)
,错误正好是
b-((a+b)-a)
(2次,或者4-5次,如果我们不知道哪个更大)。用
fma
计算乘法误差很小-它只是
fma(a,b,-a*b)
。没有
fma
这是16次相当糟糕的代码失败。而对正确舍入的
fma
的完全通用仿真甚至比这还要慢

每一次实际计算额外16次错误跟踪是一个巨大的过度杀伤力,但仅使用1-5次管道友好型错误跟踪是相当合理的,对于许多算法来说,基于50%-200%的错误跟踪和补偿开销的错误跟踪和补偿导致的错误非常小,就好像所有计算都是用两倍的比特数完成的一样,在许多情况下避免病态

有趣的是,
fma
从未在这些算法中用于计算结果,只是用于查找错误,因为查找
fma
的错误非常缓慢,因为没有
fma
的情况下,查找乘法的错误也非常缓慢


搜索的相关关键词将是“补偿霍纳方案”和“补偿点积”,霍纳方案受益更多。

taw点击一个重要的例子;更一般地说,FMA允许库编写器通过正确的舍入有效地实现许多其他浮点操作

例如,具有FMA的平台可以使用它来实现正确的四舍五入除法和平方根(PPC和安腾采用这种方法),这使得FPU基本上是一台单一用途的FMA机器。如果你好奇的话,Peter Tang和John Harrison(英特尔)以及Peter Markstein(惠普)都有一些论文解释了这种用法

taw给出的例子比跟踪误差范围更为广泛。它允许您将两个浮点数的乘积表示为两个浮点数的和,而不存在任何舍入误差;这对于实现正确的四舍五入浮点库函数非常有用。Jean-Michel Muller的书或关于
crlibm
的论文将是了解这些用途的良好开端


对于某些类型的参数,FMA在数学库样式例程中的参数缩减方面也非常有用;当一个人进行参数缩减时,计算的目标通常是一个形式为
(x-a*b)
的项,其中
(a*b)
几乎等于x本身;特别是,如果在没有FMA的情况下进行计算,则结果通常是
(a*b)
项中的舍入误差。我相信Muller在他的书中也写了一些关于这方面的内容。

关于与产品积累有关的算法,已经有了很好的解释。使用FMA的好处最大:

A fast FMA can speed up and improve the accuracy of 
many computations that involve the accumulation of products:

 * Dot product
 * Matrix multiplication
 * Polynomial evaluation (e.g., with Horner's rule)
 * Newton's method for evaluating functions.

问题是舍入的影响,而不是这个。您的回答也不正确,因为fma需要3个输入浮点单元,而不是标准的2个输入,浮点寄存器文件中的额外端口,以及更宽的浮点加法器。这不是免费的,这是以牺牲其他硬件为代价对fma支持的折衷。taw:您询问了什么算法从fma中受益,在一些示例中,舍入是一个非常重要的好处。我回答了第一部分,即大多数算法都会受益。除非你明确告诉编译器b*c+d是可以的(使用-ffast math或类似的方法),否则编译器不能合法地用FMA替换b*c+d,因为它会干扰结果。@Stephelin:假设
b
c
,的计算,而且
d
不会改变状态或产生其他副作用,这样的硬件优化如何“干扰结果”@stakx:浮点指令集中的许多复合指令都存在,因为舍入误差会淹没结果。示例:如果取e^(接近于零),结果接近于1,但这大大限制了精度。如果有一条指令表示e^epsilon-1,那么硬件可以提供更高的精度。任何给定的高级语言都可以定义为提供对更精确指令的访问,或在可识别的情况下重写表达式树。前者更具预测性