在C / C ++中,您可以设置以下代码:
double a, b, c;
...
c = (a + b) / 2;
这与以下内容完全相同:
c = (a + b) * 0.5;
我想知道哪个更好用。一项操作从根本上比另一项更快吗?
答案 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处理器的优化指南,分别提供了fdiv
和fmul
- 42和6的数据。对于DIVPS,DIVPD DIVSS和DIVSD(除法),SSE版本更接近,24(单)或27(双)周期,并且对于所有形式的乘法,6个周期。
从内存来看,英特尔的数据并不遥远。