优化求和循环

Optimizing summation loops

本文关键字:循环 求和 优化      更新时间:2023-10-16

我想在C++中实现汉克尔变换。从向量inout的变换本身(称为dhtidht)定义为

out(m) = sum_{n=0}^N c_{m,n}*in(n)

c定义为矩阵。因此,我通过以下方式实现它(使用 armadillo):

void HT::dht(const arma::cx_colvec &in, arma::cx_colvec &out)
{
    if(out.size() != in.size())
        out = arma::cx_colvec(in.size());
//#pragma omp parallel for
    for(size_t i = 0; i < in.size(); ++i)
        F(i) = (in[i] * r_max / bessel_zeros[i]);
    std::complex<double> G_0;
    for(size_t i = 0; i < in.size(); ++i)
    {
        G_0 = 0;
        for(size_t j = 0; j < in.size(); ++j)
            G_0 += c(i, j) * F[j];
        G(i) = G_0;
    };
//#pragma omp parallel for
    for(size_t i = 0; i < in.size(); ++i)
        out(i) = (G[i] / rho_max * 
        bessel_zeros[i]);
}

提高此函数速度的最佳方法是什么(根据 valgrind 的说法,这是我的代码中最耗时的函数)?我已经使用 OpenMP 测试了该功能,使用 #pragma 命令,但这甚至减慢了它的速度。我还能做些什么来提高函数的速度?

目前该程序是使用

g++ -I -O2 -g -march=native -std=gnu++17 -fopenmp main.cpp -lm -larmadillo -lgomp -lpthread -lX11 -L/opt/boost/lib -lboost_system -o main

编辑:我注意到我也可以更简洁地编写代码

F = in % (r_max / bessel_zeros);
G = c * F;
out = G % (bessel_zeros / rho_max);
这给了我 12.557 毫秒的

加速比,而 10.082 个元素的 500 毫秒,以及 359.787 毫秒对 312.383 毫秒的 2500 个元素。还有我可以优化的东西吗?

您可以计算一次"r_max/bessel_zeros"和"r_max * bessel_zeros"并将它们存储在数组中。

有没有理由只使用优化级别为 2 (-O2) 而不是 3 的编译器?

休息看起来不错。我不认为你可以把它播种很多。