乘法比浮动除法快吗?

时间:2013-07-26 13:55:24

标签: c++ c performance optimization

在C / C ++中,您可以设置以下代码:

double a, b, c;
...
c = (a + b) / 2;

这与以下内容完全相同:

c = (a + b) * 0.5;

我想知道哪个更好用。一项操作从根本上比另一项更快吗?

3 个答案:

答案 0 :(得分:36)

乘法比除法更快。在大学时,我被教导说,除法是乘法的六倍。实际时序取决于体系结构,但一般来说,乘法永远不会慢,甚至像分裂一样慢。如果舍入误差允许,请始终优化代码以使用乘法。

所以在一个例子中,这通常会更慢......

for (int i=0; i<arraySize; i++) {
    a[i] = b[i] / x;
}

......比......

y=1/x;
for (int i=0; i<arraySize; i++) {
    a[i] = b[i] * y;
}

当然,对于舍入误差,您将使用第二种方法松散(稍微)一些精度,但除非您反复计算x=1/x;,否则不会引起太多问题。

修改

仅供参考。我通过在谷歌上搜索来挖掘第三方对操作时间的比较。

http://gmplib.org/~tege/x86-timing.pdf

查看MUL和DIV上的数字。这表示差异在5到10倍之间,具体取决于处理器。

答案 1 :(得分:25)

浮点乘法通常比浮点除法占用更少的周期。但是对于文字操作数,优化器很清楚这种微优化。

答案 2 :(得分:24)

在这种情况下,编译器很可能会将除法转换为乘法,如果它“认为”它更快。在浮点中除以2也可能比其他浮点除法更快。如果编译器没有转换它,使用乘法可能会更快,但不确定 - 取决于处理器本身。

在编译器无法确定这样做是否“安全”的情况下,手动使用乘法而不是除法的增益可能非常大(例如,0.1在浮点数中不能精确地存储为0.1,它变成0.10000000149011612)。有关AMD处理器的数据,请参见下文,可以将其视为该类的代表。

为了判断你的编译器是否做得好,为什么不编写一些代码来进行实验。确保你编写它,以便编译器不只是计算一个常量值并丢弃循环中的所有计算。

修改:

AMD针对Family 15h处理器的优化指南,分别提供了fdivfmul - 42和6的数据。对于DIVPS,DIVPD DIVSS和DIVSD(除法),SSE版本更接近,24(单)或27(双)周期,并且对于所有形式的乘法,6个周期。

从内存来看,英特尔的数据并不遥远。