2013-05-28 122 views
17

我的程序在std::pow(double,int)函数中花费了90%的CPU时间。准确性不是这里主要关心的问题,所以我想知道是否有更快的选择。我想要尝试的一件事是投射浮法,执行操作,然后回到双倍(还没有尝试过);我很担心,这是不是提高性能的便携方式(不最的CPU上运行的双打本质呢?)什么比std :: pow更快?

干杯

+2

有点取决于你计算的功率 - 请显示一些代码和/或描述你的数据。 – paddy

+1

硬件在一般情况下比软件更快,这就是'pow'的一点......除非你可以对你正在做的事情施加额外的限制,否则你无法打败它。 – Mehrdad

+1

本文可能有用:http://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/ –

回答

14

它看起来像马丁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

9

取决于你需要做什么,在对数域中运行可能工作 - 也就是说,你用你的对数代替你所有的值;乘法成为加法,除法成为减法,指数乘法成为乘法。但现在加减变得昂贵和有点容易出错的操作。

4

有多大的整数?它们在编译时是否已知?计算x^2x*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的最后一个乘法。

+0

当然,这个假设奥地利人正在使用整数。目前还不清楚是否是这种情况。 – jamesdlin

+0

@jamesdin:当然他是。 *我的程序在std :: pow(double,int)函数中占用了90%的CPU时间。* –

+0

糟糕,抱歉。你是对的;我认为我的大脑今天正在度假。 > _ < – jamesdlin

相关问题