为什么浮动分裂缓慢?

时间:2009-02-03 07:16:19

标签: performance algorithm hardware

算法中有哪些浮点除法步骤?

为什么结果比说,乘法慢?

它是否像我们手工分割那样完成?通过重复除以除数,减去结果得到余数,再次对齐数字并继续直到余数小于特定值?

另外,为什么我们不是在做

而获得性能
a = b / c 

我们

d = 1 / c
a = b * d

编辑: 基本上我是在问,因为有人要求我根据权重的分配在竞争者中分配一个值。我用整数做了所有这些,后来被要求转换为浮动,这导致性能下降。我只是想知道C或C ++如何做这些会导致缓慢的操作。

6 个答案:

答案 0 :(得分:21)

FPU师通常基本上使用Newton-Raphson(或其他一些算法)得到一个倒数然后乘以该倒数。这就是为什么倒数操作比一般除法操作略快的原因。

This HP paper(这比我在谈到Newton-Raphson的大多数论文中更容易理解)有关于浮点除法的说法:

  

浮点除法和平方   root需要相当长的时间   计算而不是加法和   乘法。后两者是   直接计算,而前者是   通常用迭代计算   算法。最常见的方法是   使用无分区的Newton-Raphson   迭代得到近似值   分母的倒数   (分裂)或倒数平方   root,然后乘以   分子(除法)或输入参数   (平方根)。

答案 1 :(得分:18)

从硬件的角度来看,除法是一种迭代算法,它所花费的时间与位数成正比。目前最快的分区使用radix4算法,每次迭代生成4位结果。对于32位除法,至少需要8步。

乘法可以在一定程度上并行完成。如果不详细说明,您可以将大量乘法分解为几个较小的独立乘法。这些乘法可以再次分解,直到你处于一个位级别,或者你提前停止并在硬件中使用一个小的查找表。这使得乘法硬件从硅片房地产的角度来看很重,但也非常快。这是经典的尺寸/速度权衡。

您需要log2步骤来组合并行计算结果,因此32位乘法需要5个逻辑步骤(如果您降到最小值)。幸运的是,这5个步骤比分割步骤更简单(它只是添加)。这意味着在实践中倍数会更快。

答案 2 :(得分:6)

如维基百科文章 Division algorithm 所述,计算机中存在两种主要的划分方法:

慢速划分

使用以下重复,每次迭代找到一个数字: partialRemainder[j+1] = radix * partialRemainder[j] - quotientDigit[n-(j+1)]*denominator

快速分部

从估计开始并收敛于商。您的准确程度取决于迭代次数。

Newton-Raphson师(非常简短):

  1. 计算倒数的估计值。
  2. 计算更准确的倒数估计。
  3. 通过将被除数乘以倒数计算商。

答案 3 :(得分:1)

您无法通过

获得表现
d = 1 / c
a = b * d

你可能意味着:

d = 1 / c
a1 = b1 * d
a2 = b2 * d

这样,除法只进行一次。

分区本身比乘法慢,但是,我不知道细节。基本原因是,与sin或sqrt等函数类似,它在数学上更复杂。 IIRC,乘法在平均CPU上需要大约10个周期,而除法需要大约50个或更多。

John Mulder很好地解释了它是如何实际完成的。

答案 4 :(得分:0)

考虑一下所涉及的硬件,你会明白为什么它需要更长的时间来划分而不是相乘。这两个操作都是在浮点单元(FPU)级别完成的,甚至在整体ALU的世界中,除法电路比乘法电路更加繁忙。我怀疑这在浮点世界中只是更加痛苦,因为现在数据不仅仅是订购的最重要数字,而是按照IEEE 754标准排序。

关于四舍五入,它实际上是关于在门之间传播的信号被焊接到地面的任何地方;如果发生这种情况,你会丢失数字。不是四舍五入,而是截断。

或者您是否在使用整数来模拟浮点运算?

答案 5 :(得分:0)

浮点除法并不比整数除法慢得多,但编译器可能无法进行相同的优化。

例如,编译器可以用乘法和二进制移位替换3之间的整数除法。 此外,它可以用乘法乘以0.5替换2.0之间的浮点除法,但它不能用乘以1 / 3.0的3.0替换除法,因为1 / 3.0不能用二进制数精确表示,因此舍入误差可能会改变除法的结果。
由于编译器不知道您的应用程序对舍入错误的敏感程度(比如您正在进行天气模拟,请参阅Butterfly effect),因此无法进行优化。