进行乘法是否比在c ++中提升到2更有效率?
我正在尝试做最后的详细优化。编译器会处理吗? x * x与pow(x,2)相同?如果我没记错的话,乘法就是 出于某种原因更好,但也许在c ++ 11中没关系。
由于
答案 0 :(得分:20)
如果你将乘法与pow()
标准库函数进行比较,那么是的,乘法肯定更快。
答案 1 :(得分:6)
总的来说,你不应该担心像这样的微微优化,除非你有证据存在热点(即除非你在现实场景下描述你的代码并且已经确定了特别是一大堆代码。还要记住,你的聪明技巧实际上可能导致新处理器中的性能回归,而你的假设将不再适用。
算法更改是您获得计算优势的最佳选择。专注于此。
摆弄乘法并做一些巧妙的比特hackery ......呃那里没有那么多*因为当前一代的优化编译器在他们的工作中非常非常优秀。这并不是说他们无法被击败。他们可以,但不是很容易,可能只有少数人喜欢Agner Fog。
*当然有例外。
答案 2 :(得分:5)
在性能方面,始终进行测量以备份您的假设。除非你有一个证明该理论正确的基准,否则永远不要相信理论。
另外,请记住x ^ 2
不在C ++中产生2的平方:
#include <iostream>
int main()
{
int x = 4;
std::cout << (x ^ 2); // Prints 6
}
答案 3 :(得分:2)
pow()的实现通常涉及对数,乘法和expononention,因此它将比单纯的乘法更长时间。大多数现代高端处理器可以在几个时钟周期内对整数值进行乘法运算,并为浮点乘法运算十几个周期。取幂可以作为复杂(微编码)指令完成,需要几十个或更多个周期,或者作为一系列乘法和加法(通常具有交替的正数和负数,但不一定是)。指数是一个类似的过程。
在较低范围的处理器(例如ARM或较旧的x86处理器)上,结果更糟。在一个浮点运算中,或在某些处理器中,甚至浮点计算中的数百个周期是许多整数运算,它们执行与更高级处理器上的浮点指令相同的步骤,因此pow()
所需的时间可能是数十个周期,相比十几个左右的乘法。
无论使用哪种选择,整个计算都会比简单的乘法长得多。
当指数大或不是整数时,pow()
函数很有用。即使对于相对较大的指数,您也可以通过多次平方或立方来进行计算,并且它将比pow()
更快。
当然,有时编译器可能能够弄清楚你想要做什么,并将其作为一系列乘法作为优化。但我不会依赖于此。
最后,总而言之,对于性能问题:如果它对您的代码非常重要,那么测量它 - 您的编译器可能比您更精简。如果性能不重要,则执行使代码最具可读性的计算。
答案 4 :(得分:1)
pow
是库函数,而不是运算符。除非编译器能够优化调用(它通过利用其对标准库函数的行为的知识合法地进行调用),否则调用pow()
将强加函数调用和所有额外函数的开销。 pow()
函数必须执行的操作。
pow()
的第二个参数不必是整数;例如pow(x, 1.0/3.0)
将为您提供x
的立方根的近似值。这将需要一些相当复杂的计算。如果第二个参数是一个小的整数值,它可能会回退到重复乘法,但是它必须在运行时检查它。
如果要平方的数字是整数,pow
将涉及将其转换为double
,然后将结果转换回整数类型,这相对较贵并且可能导致细微的舍入错误
使用x * x
很可能比pow(x, 2)
更快,更可靠,而且更简单。 (在大多数情况下,简单性和可靠性比速度更重要。)
答案 5 :(得分:0)
C / C ++没有本地&#34;电源&#34;运营商。 ^
是按位异或或(xor)。如上所述,pow
功能可能正是您所寻找的。 p>
实际上,对于平方整数,x*x
是最直接的方法,如果可用,某些编译器可能会将其优化为机器操作。
答案 6 :(得分:0)
您应该阅读以下链接 Why doesn't GCC optimize a*a*a*a*a*a to (a*a*a)*(a*a*a)?
pow(x,2)很可能会转换为x x。然而,诸如pow(x,4)之类的更高功率可能无法尽可能最佳地完成。例如,pow(x,4)可以在3次乘法x x x x或两次(x x)(x * x)中完成,具体取决于您需要多严格的浮点定义(默认情况下我认为它将使用3次乘法。
有趣的是看看例如pow(x * x,2)产生的是什么,有没有-ffast-math。
答案 7 :(得分:0)
你应该研究一下boost.math的pow功能模板。它将指数作为模板参数并自动计算,例如,pow&lt; 4&gt;(x)为(x * x)*(x * x)。