简体   繁体   English

如何提高权力? 是否值得使用pow(x,2)?

[英]How raise to power works? Is it worth to use pow(x, 2)?

Is it more efficient to do multiplication than raise to power 2 in c++? 在C ++中做乘法比加2幂更有效吗?

I am trying to do final detailed optimizations. 我正在尝试进行最终的详细优化。 Will the compiler treat x*x the same as pow(x,2)? 编译器将x * x与pow(x,2)一样对待吗? If I remember correctly, multiplication was better for some reason, but maybe it does not matter in c++11. 如果我没记错的话,由于某种原因,乘法会更好,但是在c ++ 11中也许没关系。

Thanks 谢谢

如果您将乘法与pow()标准库函数进行比较,那么可以,乘法肯定更快。

I general, you should not worry about pico-optimizations like that unless you have evidence that there is a hot-spot (ie unless you've profiled your code under realistic scenarios and have identified a particular chunk of code. Also keep in mind that your clever tricks may actually cause performance regressions in new processors where your assumptions will no longer hold. 一般而言,除非您有证据证明存在热点(例如,除非您已经在现实情况下对代码进行了分析并确定了特定的代码块,否则,您就不必担心像这样的微微优化)。您的巧妙技巧实际上可能会导致新处理器的性能下降,而您的假设将不再成立。

Algorithmic changes are where you will get the most bang for your computing buck. 算法上的改变是您最大的收获。 Focus on that. 集中精力。

Tinkering with multiplications and doing clever bit-hackery... eh not so much bang there* Because the current generation of optimizing compilers is really quite excellent at their job. 修改乘法并进行巧妙的位骇客攻击……可不是那么厉害*,因为当前这一代优化编译器的工作确实非常出色 That's not to say they can't be beat. 这并不是说他们不能被击败。 They can, but not easily and probably only by a few people like Agner Fog. 它们可以但不容易,并且可能只有像Agner Fog这样的少数人才能做到。

* there are, of course, exceptions. * 当然也有例外。

When it comes to performance, always make measurements to back up your assumptions. 在性能方面,请务必进行测量以支持您的假设。 Never trust theory unless you have a benchmark that proves that theory right. 除非您有可以证明该理论正确的基准,否则请不要相信理论。

Also, keep in mind that x ^ 2 does not yield the square of 2 in C++: 另外,请记住, x ^ 2 不会产生2的平方在C ++:

#include <iostream>

int main()
{
    int x = 4;
    std::cout << (x ^ 2); // Prints 6
}

Live example . 现场例子

The implementation of pow() typically involves logarithms, multiplication and expononentiaton, so it will DEFINITELY take longer than a simple multiplication. pow()的实现通常涉及对数,乘法和指数,因此,与简单的乘法相比,它肯定需要更长的时间。 Most modern high end processors can do multiplication in a couple of clockcycles for integer values, and a dozen or so cycles for floating point multiply. 大多数现代高端处理器可以在几个时钟周期内对整数值进行乘法,而在十几个周期内对浮点乘法进行乘法。 exponentiation is either done as a complex (microcoded) instructions that takes a few dozen or more cycles, or as a series of multiplication and additions (typically with alternating positive and negative numbers, but not certainly). 取幂可以通过一个复杂的(微码的)指令来完成,该指令需要几十个或更多个周期,也可以是一系列的乘法和加法运算(通常使用正负数交替,但不一定)。 Exponentiation is a similar process. 求幂是一个类似的过程。

On lower range processors (eg ARM or older x86 processors), the results are even worse. 在较低范围的处理器(例如ARM或较旧的x86处理器)上,结果甚至更糟。 Hundreds of cycles in one floating point operation, or in some processors, even floating point calculations are a number of integer operations that perform the same steps as the float instructions on more advanced processors, so the time taken for pow() could be thousands of cycles, compared to a dozen or so for a multiplication. 一个浮点运算或某些处理器中的数百个周期,甚至浮点计算都是许多整数运算,它们执行与更高级处理器上的float指令相同的步骤,因此pow()花费的时间可能是数千个周期,而一个乘法则要打一打左右。

Whichever choice is used, the whole calculation will be significantly longer than a simple multiplication. 无论使用哪种选择,整个计算都将比简单的乘法长得多。

The pow() function is useful when the exponent is either large, or not an integer. 当指数很大或不是整数时, pow()函数很有用。 Even for relatively large exponents, you can do the calculation by squaring or cubing multiple times, and it will be faster than pow() . 即使对于相对较大的指数,也可以通过多次平方或求立方来进行计算,这将比pow()更快。

Of course, sometimes the compiler may be able to figure out what you want to do, and do it as a sequence of multiplications as a optimization. 当然,有时编译器也许能够弄清楚您想做什么,并可以通过一系列乘法来进行优化。 But I wouldn't rely on that. 但是我不会依靠这一点。

Finally, as ALWAYS, for performance questions: If it's really important to your code, then measure it - your compiler may be smarter than you thin. 最后,总是会遇到性能问题:如果它对您的代码确实很重要,请对其进行评估-您的编译器可能比您的精简智能。 If performance isn't important, then perform the calculation that is the makes the code most readable. 如果性能并不重要,请执行使代码更具可读性的计算。

pow is a library function, not an operator. pow是库函数,不是运算符。 Unless the compiler is able to optimize out the call (which it legitimately do by taking advantage of its knowledge of the behavior of the standard library functions), calling pow() will impose the overhead of a function call and of all the extra stuff the pow() function has to do. 除非编译器能够优化调用(通过利用其对标准库函数行为的了解来合理地做到这一点),否则调用pow()会增加函数调用和所有其他额外开销的开销。 pow()函数必须执行。

The second argument to pow() doesn't have to be an integer; pow()的第二个参数不必是整数。 for example pow(x, 1.0/3.0) will give you an approximation of the cube root of x . 例如pow(x, 1.0/3.0)将为您提供x的立方根的近似值。 That's going to require some fairly sophisticated computations. 这将需要一些相当复杂的计算。 It might fall back to repeated multiplication if the second argument is a small integral value, but then it has to check for that at run time. 如果第二个参数是一个较小的整数值,它可能会退回到重复乘法,但是随后它必须在运行时检查该值。

If the number you want to square is an integer, pow will involve converting it to double , then converting the result back to an integer type, which is relatively expensive and could cause subtle rounding errors. 如果要平方的数字是整数,则pow将涉及将其转换为double ,然后将结果转换回整数类型,这相对昂贵,并且可能会导致细微的舍入错误。

Using x * x is very likely to be faster and more reliable than pow(x, 2) , and it's simpler. 使用x * x可能比pow(x, 2)更快,更可靠,并且更简单。 (In most contexts, simplicity and reliability are more important considerations than speed.) (在大多数情况下,简单性和可靠性比速度更重要。)

C/C++ does not have a native "power" operator. C / C ++没有本地“幂”运算符。 ^ is the bitwise exclusive or (xor). ^是按位异或(xor)。 Thus said, the pow function is probably what you are looking for. 因此, pow函数可能正是您要寻找的。

Actually, for squaring an integer number, x*x is the most immediate way, and some compiler might optimize it to machine operation if available. 实际上,要对整数进行平方运算, x*x是最直接的方法,某些编译器可能会对其进行优化以适应机器操作(如果可用)。

You should read the following link Why doesn't GCC optimize a*a*a*a*a*a to (a*a*a)*(a*a*a)? 您应该阅读以下链接, 为什么GCC不能将a * a * a * a * a * a优化为(a * a * a)*(a * a * a)?

pow(x,2) will most likely be converted to x x. pow(x,2)很可能会转换为x x。 However, higher powers such as pow(x,4) may not be done as optimally as possible. 但是,诸如pow(x,4)之类的较高功率可能无法做到最佳。 For example pow(x,4) could be done in 3 multiplications x x x x or in two (x x) (x*x) depending on how strict you require the floating point definition to be (by default I think it will use 3 multiplications. 例如pow(x,4)可以3乘x x x x x或2(x x) (x * x)来完成,具体取决于您对浮点定义的严格要求(默认情况下,我认为它将使用3次乘法。

It would be interesting to see what for example pow(x*x,2) produces with and without -ffast-math. 看看pow(x * x,2)在有和没有-ffast-math的情况下产生的结果会很有趣。

you should look into boost.math's pow function template. 您应该查看boost.math的pow函数模板。 it takes the exponent as template parameter and automatically calculate, for example, pow<4>(x) as (x*x)*(x*x). 它以指数作为模板参数,并自动将pow <4>(x)计算为(x * x)*(x * x)。

http://www.boost.org/doc/libs/1_53_0/libs/math/doc/sf_and_dist/html/math_toolkit/special/powers/ct_pow.html http://www.boost.org/doc/libs/1_53_0/libs/math/doc/sf_and_dist/html/math_toolkit/special/powers/ct_pow.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM