我的程序在该std::pow(double,int)函数中花费了90%的CPU时间.准确性不是这里的主要关注点,所以我想知道是否有更快的替代品.我想要尝试的一件事是铸造浮动,执行操作然后再加倍(尚未尝试过); 我担心这不是一种提高性能的可移植方式(不管大多数CPU本质上都是双重操作吗?)
干杯
Sha*_*our 15
看起来Martin Ankerl有一些关于此的文章,C/C++中的Optimized Approximative pow()是一个,它有两个快速版本,一个如下:
inline double fastPow(double a, double b) {
union {
double d;
int x[2];
} u = { a };
u.x[1] = (int)(b * (u.x[1] - 1072632447) + 1072632447);
u.x[0] = 0;
return u.d;
}
Run Code Online (Sandbox Code Playgroud)
从草案标准部分9.5 [class.union]中依赖于C++中未定义行为的联合类型惩罚:
在并集中,至多一个非静态数据成员可以在任何时间处于活动状态,也就是说,任何时候最多一个非静态数据成员的值都可以存储在并集中.[...]
从不同的工会成员阅读的做法比最近写的那个(称为"打字式")很常见.即使使用-fstrict-aliasing,只要通过union类型访问内存,就允许类型为punning
但是这并不是普遍的,正如本文所指出的那样,正如我在这里的回答中所指出的,使用memcpy应生成相同的代码并且不会调用未定义的行为.
他还链接到第二个优化的pow()近似Java,C/C++和C#.
第一篇文章还链接到自己的微基准这里
您的整数有多大?他们在编译时知道吗?这是好得多计算x^2的x*x,而不是pow(x,2)。注意:几乎所有pow()对整数次幂的应用都涉及将某个数字提高到第二或三次幂(如果是负指数,则乘以逆)。pow()在这种情况下,使用是过大的。为这些小的整数幂使用模板,或仅使用x*x。
如果整数很小,但在编译时未知(例如在-12和+12之间),则乘法仍然有效pow()并且不会丢失精度。您不需要十一个乘法即可计算x ^ 12。四个会做。使用x ^(2n)=(x ^ n)^ 2和x ^(2n + 1)= x *((x ^ n)^ 2)的事实。例如x ^ 12是((x * x * x)^ 2)^ 2。两次乘法计算x ^ 3(x * x * x),再乘一次计算x ^ 6,最后一次乘法计算x ^ 12。