2017-11-05 11 views
1

C++でハンケル変換を実装したいと思います。 outのベクターinから(dhtと​​呼ばれる)変換自体は行列として定義c集計ループを最適化する

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

として定義されます。したがって、私は(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のに応じて、自分のコードの中で最も時間のかかる機能です)この機能の速度を改善するための最良の方法は何ですか?私は既に#pragmaコマンドを使用してOpenMPでこの機能をテストしましたが、速度が遅くなりました。機能の速度を向上させるために他に何ができますか?

現在、このプログラムは

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 

Editを使用してコンパイルされています。私は私の12.557ミリ対のための10.082ミリ秒のスピードアップを与える

F = in % (r_max/bessel_zeros); 
G = c * F; 
out = G % (bessel_zeros/rho_max); 

ように、より簡潔に、コードを書くことができることに気づきました500要素、および359.787ミリ秒対312.383ミリ秒、2500要素。まだ最適化できるものはありますか?

+0

ベクターのサイズは? – Alex

+0

固定ですが、500要素と50000要素の間の実行によって異なります。 –

+0

要素ごとの処理で500と50000の要素の違いが分かりましたか? – Alex

答えて

0

'r_max/bessel_zeros'と 'r_max * bessel_zeros'を一度計算して配列に格納できます。

最適化レベル2(-O2)で、3ではないコンパイラだけがあるのはなぜですか?

残りはよく見えます。私はあなたがそれをたくさん植えることはできないと思う。

+0

-O3は私の測定結果によるとさらに遅くなります –

+0

なぜこのようなことが起こるのか? – schorsch312

+0

いくつかの悪い最適化を仮定しますが、そうでなければアイデアはありません –