2016-04-27 3 views
-1

私は次のコード部分を持っています。N = 3000のサンプルで実行します.C++のシーケンシャルコードは3秒早くなります。OpenMPコードC++は遅いthatn C++

このコードは計算された値で配列jsd [N]を埋めており、最大値とその位置を探したいと思います。 だから 1-これは正しいopenmpの変換であり、もっとprofissionalにするためのより良い提案がある 2つの理由は、同等のC++コードが遅いのはなぜですか?また、より多くのスレッドを作成するほど遅くなります。事前

double maxval = 0; 
int pos = -1; 
double jsd[N]; 
#pragma omp parallel for num_threads(4) 
for (int i = 0; i < N; i++) { 
    double Hl = obj.function1(sequenceVctr, i, LEFT); 
    double Hr = obj.function1(sequenceVctr, i, RIGHT); 
    jsd[i] = obj.function2(H, i + 1, N, Hl, Hr); 

    if (jsd[i] >= maxval) { 
     #pragma omp critical 
     { 
     maxval = jsd[i]; 
     pos = i; 
     } 
    } 
} // for 

更新中

感謝:ここ

は、新しいコードが、それでも遅いと複数のスレッドで遅く取得することです。 私は次のようにコードを更新します。それでも多くのスレッド

double maxval = 0; 
int pos = -1; 
double jsd[N]; 
#pragma omp parallel num_threads(50) 
for (int i = 0; i < N; i++) { 
    double Hl = obj.function1(sequenceVctr, i, LEFT); 
    double Hr = obj.function1(sequenceVctr, i, RIGHT); 
    jsd[i]= obj.function2(H, i + 1, N, Hl, Hr); 

} // for 
#pragma omp master 
{ 
    vector<double> jsd2 (jsd,jsd+N); 
    vector<double>::iterator jsditer; 
    jsditer = std::max_element(jsd2.begin(), jsd2.end()); 
    maxval=*jsditer; 
    pos=std::distance(jsd2.begin(),jsditer) ; 
// cout<<"pos"<<pos<<endl; 
} 
#pragma omp barrier 
+0

どのように時間を測定しますか? – user463035818

+0

答えはありませんが、あなたのif(jsd [i]> = maxval)がクリティカルセクションに属していると思います – Shmoopy

+0

あなたの投稿をもっと見やすくするために少し時間がかかりますか? –

答えて

3

ため遅くなる私は示唆している最初の最適化は、まずstd::max_element()を経由して最大の要素を見つけ、ループ内のすべてのJSD値を計算することです。 この方法では、スレッドを強制的に同期させません。

OpenMPではなくIntel TBBに移行し、parallel_reduce()を使用します。

しかし、最大の問題は、評価している目的関数がどれほど複雑かということです。

+2

あなたの最初の段落はまさに私が提案するものです。同期はマルチスレッドのメリットを大きく制限する可能性があります – vu1p3n0x

+0

function1はハッシュマップを持つアプリケーションを遅くするものですが、function2はsimiple計算です –

+0

もあります。 std :: max_element()はvecorsでのみ動作し、jsdは配列であり、並列コードでベクトルに挿入(push_back)したいときは衝突が発生します。 –