taw*_*taw 14 floating-point fma
fma(a,b,c)
相当于a*b+c
除了不舍入中间结果.
你能不能给我一些算法的例子,这些算法可以从避免这种舍入中获益?
这并不明显,因为我们避免的乘法后的舍入往往比加法后的舍入更少有问题,而我们没有.
taw打了一个重要的例子; 更一般地说,FMA允许库编写者通过正确的舍入有效地实现许多其他浮点运算.
例如,具有FMA的平台可以使用它来实现正确的舍入分割和平方根(PPC和Itanium采用这种方法),这使得FPU基本上是单用途FMA机器.Peter Tang和John Harrison(英特尔)和Peter Markstein(HP)有一些文章可以解释这种用法,如果你很好奇的话.
示例taw给出的功能比跟踪误差范围更广泛.它允许您将两个浮点数的乘积表示为两个浮点数的总和,没有任何舍入误差; 这在实现正确舍入的浮点库函数时非常有用.Jean-Michel Muller的书或论文crlibm
将是了解这些用途的更好起点.
对于某些类型的参数,FMA在减少数学库样式例程中的参数方面也非常有用; 当一个人正在进行参数减少时,计算的目标通常是形式的一个术语(x - a*b)
,其中(a*b)
几乎等于x本身; 特别是(a*b)
,如果没有FMA计算,结果通常是术语中的舍入误差的顺序.我相信穆勒也在他的书中写了一些关于这一点.
到目前为止我唯一发现的是"无错误的转换".对于任何浮点数错误来自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
.
相关的搜索关键词将是"补偿的Horner计划"和"补偿点积",而Horner计划将受益更多.