我的程序在std::pow(double,int)
函数中花费了90%的CPU时间。准确性不是这里主要关心的问题,所以我想知道是否有更快的选择。我想要尝试的一件事是投射浮法,执行操作,然后回到双倍(还没有尝试过);我很担心,这是不是提高性能的便携方式(不最的CPU上运行的双打本质呢?)什么比std :: pow更快?
干杯
我的程序在std::pow(double,int)
函数中花费了90%的CPU时间。准确性不是这里主要关心的问题,所以我想知道是否有更快的选择。我想要尝试的一件事是投射浮法,执行操作,然后回到双倍(还没有尝试过);我很担心,这是不是提高性能的便携方式(不最的CPU上运行的双打本质呢?)什么比std :: pow更快?
干杯
它看起来像马丁Ankerl有一些关于此文章,Optimized Approximative pow() in C/C++是一个,它有两个快速版本,一个是如下:
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;
}
,它通过联合依赖型双关其是不确定的行为在C++中,从标准的牵伸部9.5
[class.union]:
在联盟中,非静态数据成员的至多一个可以是一个任何时候都可以存储,也就是说,在 的值中,大多数非静态数据成员可以随时存储在工会中。 [...]
但大多数编译器,包括gcc support this with well defined behavior:
从不同的工会会员阅读的做法比一个最近写入(称为“类型双关”)是常见的。即使-fstrict走样,类型punning也是允许的,所提供的存储器是通过联合类型
访问,但这不是普遍作为this article points out和作为我point out in my answer here使用memcpy
应产生相同的代码和不调用未定义行为。
他还链接到第二个Optimized pow() approximation for Java, C/C++, and C#。
第一篇文章还链接到自己的微基准here
取决于你需要做什么,在对数域中运行可能工作 - 也就是说,你用你的对数代替你所有的值;乘法成为加法,除法成为减法,指数乘法成为乘法。但现在加减变得昂贵和有点容易出错的操作。
有多大的整数?它们在编译时是否已知?计算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的最后一个乘法。
有点取决于你计算的功率 - 请显示一些代码和/或描述你的数据。 – paddy
硬件在一般情况下比软件更快,这就是'pow'的一点......除非你可以对你正在做的事情施加额外的限制,否则你无法打败它。 – Mehrdad
本文可能有用:http://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/ –