2016-08-11 14 views
3

私はompタスク(ビジュアルスタジオ2015を使用)を使用することができないため、ネストされたループタスクの回避策を見つけようとしています。コードは以下の通りである:OMP 2.0ネストされたForループ

#pragma omp parallel 
    { 
     for (i = 0; i < largeNum; i++) 
     { 
#pragma omp single 
     { 
      //Some code to be run by a single thread 
      memset(results, 0, num * sizeof(results[0])); 
     } 
#pragma omp for 
      for (n = 0; n < num; n++) { 
       //Call to my function 
       largeFunc(params[n], &resulsts[n]) 
      } 
     } 
#pragma omp barrier 
    } 

私はすべての私のスレッドがlargeNum時間を実行したいのですが、ゼロに設定することがmemsetのを待ち、その後、私はlargeFuncは、各スレッドで実行されたいです。私が見つけたデータ依存性はありません。

私はこの時点で、ompのディレクティブがすべて私の頭の中で混乱しているのを見ました。このソリューションは機能しますか?タスクなしで行うより良い方法はありますか?

おかげで、 アリック

+0

'for'ループで' largeFunc'を使って '#pragma omp parallel for'を使うのではなく、残りのompを削除してみませんか?そのループは、あなたが並行して実行したい唯一のものと思われます。 – amaurea

+0

私はlargeNumループをスレッド間で分割したくありません。 –

答えて

1

何ちょうどこのコードは?

限り、私はあなたの問題を理解し、intialisation部分が singleディレクティブを必要とせずに世話をしなければならない
#pragma omp parallel private(i, n) 
for (i = 0; i < largeNum; i++) { 
    #pragma omp for 
    for (n = 0; n < num; n++) { 
     results[n] = 0; 
     largeFunc(param[n], &results[n]); 
    } 
} 

は、resultsの実際の型は、あなたの最初のコードが欠けていた、また0に割り当てをサポート提供しましたprivate(i)宣言の最後に、barrierは必要ありません。

+0

@ Giles largeenumをスレッド間で分割するのではなく、内側のループから分割することは望ましくありません。このインプリメンテーションにはインナーの後に暗黙のバリアがありますか? –

+1

この実装はスレッドのチームを生成し、すべてが 'i'反復の全範囲を実行し、各反復の内側で' n'ループで作業を共有します。 'omp for'指示の終わりに暗黙のバリアがあり、チームのどのスレッドもすべてのスレッドが現在のものを終了する前に新しい' i'繰り返しを開始するのを防ぎます。だから、私が取ることは、あなたが望んだことをすることです(私はあなたが最初に望んでいた理由、つまりおそらくベンチマークを見ることができませんが)。 – Gilles

+0

これはうまくいきました:)そしてそれはベンチマークのためです –

1

なぜあなたのスレッドはすべてlargeNUMを実行しますか?あなたは、私はあなたが最初のものが欲しいと感じしかし、あなたは、私に

for (i = 0; i < largeNum; i++) 
    { 
     //Some code to be run by a single thread 
     memset(results, 0, num * sizeof(results[0])); 

#pragma omp parallel for 
     for (int n = 0; n < num; n++) { 
      //Call to my function 
      largeFunc(params[n], &resulsts[n]) 
     } 
    } 

を依存していない場合は何らかの方法

#pragma omp parallel for 
    for (int i = 0; i < largeNum; i++) 
    { 
#pragma omp single 
    { 
     //Some code to be run by a single thread 
     memset(results, 0, num * sizeof(results[0])); 
    } 
#pragma omp barrier 

// #pragma omp for -- this is not needed since it has to be coarse on the outermost level. However if the below function does not have anything to do with the outer loop then see the next example 
     for (n = 0; n < num; n++) { 
      //Call to my function 
      largeFunc(params[n], &resulsts[n]) 
     } 
    } 

} 

はいた場合にあなたのlargeFunc内部インデックスiに依存します。一般的には、一番外側のループを並列化します。内部ループにプラグマを置くと、実行する作業が十分でない場合、オーバーヘッドによってコードが遅くなります。

+0

依存関係はありません。プラグマを内部に置かないとスレッドに参加しませんか?私はオーバーヘッドを最小化するためにスレッドをフォークに保つようにしています –

+0

あなたはどんな種類の依存関係も持っていません。あなたは幸運にも、 '#pragma omp for nowait'を使うことができます。nowaitは暗黙のバリアを削除します。 – itsnevertoobadtoaskforhelp

+0

内部の後にすべてのスレッドを追加することを除いて、依存関係はありません。 –

関連する問題