使用常数双指数优化幂的和

我已经实现了一种算法,在某些时候需要计算矢量元素的功率总和。 权力是一个积极的双重,在循环过程中不变。 我想通了,这个计算是目前我的程序的瓶颈,并想知道是否有办法加快下面的代码片段:

double SumOfPowers(std::vector<double>& aVector,double exponent)
{
    double help = 0;
    size_t sizeOfaVector = aVector.size();
    for (size_t k = 0; k < sizeOfaVector; k++)
    {
        help += std::pow(aVector[k], exponent);
    }
    return help;
}

我有一种感觉,就好像可以利用指数在循环期间不变的事实并减少昂贵的std :: pow调用。 有没有人知道更好的实现方式,或者是否有可以使用的库函数来完成这项工作?


首先,检查循环是否是向量化的。 为此,使用-O3编译你的程序(这里和下面我假设gcc编译器;我不太了解其他编译器,但我希望他们有类似的选项)。 添加-ftree-vectorizer-verbose=2选项以获取关于哪些循环被矢量化的详细输出。 你可能想玩弄选项来获得你想要的输出。

如果循环没有矢量化,那么你可以使它矢量化。 您可能需要更改循环结构(例如,首先将所有权限计算为单独的数组,然后才计算总和),或者使用某种方式告知编译器的更多信息,如restrict声明,请参阅“使用gcc 4.7进行矢量化“以获得更多讨论。 在最糟糕的情况下,我认为,您可以手动实现矢量化,我记得有这样的功能,请参阅Intel的参考资料或“用C ++实现SSE SIMD的实用指南”。

对于Visual Studio,首先添加/Qvec-report:2选项以获得详细报告。 以上所有其他建议也适用,您只需要找到相应的MSVC选项。


另一种加快速度的方法是使用-ffast-math选项来牺牲精度。 AFAIK,标准的pow函数使用一些先进的逻辑来检查基数或指数是否真的接近1以避免精度问题。 如果这不是你的情况,你可能不需要这个逻辑。 我认为,尽管你可能想要检查它,但是-ffast-math会降低它。

无论如何,你可以用exp(log(...)*...)替换pow来避免手动检查。 这不会给你提速,但你可能会注意到一些收获。 另外,如果您经常将相同的向量提升为不同的指数,则可以预先计算log


不,恒指数不允许进行可行的优化,除非您的值经常重复(如果是这样的话:memoize)。 并行是你最好的选择在这里(或不pow在所有)

链接地址: http://www.djcxy.com/p/85725.html

上一篇: Optimize sum of powers with constant double exponent

下一篇: Can I compute pow(10,x) at compile