2017-11-20 19 views
0

用せず、私は、次のOpenMPの不均等な負荷ループ

したがって
while(counter < MAX) { 
    #pragma omp parallel reduction(+:counter) 
    { 
    // do monte carlo stuff 
    // if a certain condition is met, counter is incremented 

    } 
} 

ように見えるOpenMPのコードを持って、アイデアは、平行部があれば、カウンタが一定以下であるように使用可能なスレッドによって実行されることをあります値。シナリオによっては(私はここでMCのことをするのでランダムなので)、計算は他のものより長くかかるかもしれないので、並列の最後の暗黙的な障壁のために明白になる作業者の間に不均衡がありますセクション。

#pragma omp parallelのように見えるのは、これを回避する方法(nowaitディレクティブ/ダイナミックスケジューリング)があるかもしれませんが、forループの上位反復番号がわからないため、これを使用できません。

どのようなアイデアやデザインパターンそのような状況に対処するには?

よろしくお願いいたします。

答えて

0

すべてを1つの並列セクションで実行し、counterにアトミックにアクセスします。

int counter = 0; 
#pragma omp parallel 
while(1) { 
    int local_counter; 
    #pragma omp atomic read 
    local_counter = counter; 
    if (local_counter >= MAX) { 
      break; 
    } 
    // do monte carlo stuff 
    // if a certain condition is met, counter is incremented 
    if (certain_condition) { 
     #pragma omp atomic update 
     counter++; 
    } 
} 

原子アクセスのため、while条件で直接チェックすることはできません。 このコードはオーバーシュートします。つまり、パラレルセクションの後にcounter > MAXが可能です。 counterは多くのスレッドによって共有され、読み書きされることに注意してください。

+0

ありがとうございます - 私はすぐに試してみます。削減条項はもう必要なくなったと思いますか?つまり、原子操作を使用すると、コードはすでにこれを処理しています。 – tomseidel1

+0

はい、この場合還元節は間違っています - 残念で良いキャッチです。 Atomicsは、1)「カウンター」が正しい時間量の合計を更新し、2)常に有効な値を読み取ることに注意します。 – Zulan

+0

もう1つの一般的な質問:スレッドが複雑な構造体にアクセスする必要がある状況を処理する最善の方法は何ですか(これは、たとえば、動的に配列を割り当てられたメンバを意味します)。私の現在のアプローチは単に共有されており、私は何の問題にも気付かなかった。 しかし、私は疑問に思っています。なぜ#pragma atomic readが必要なのでしょうか? firstprivateは構造体にとってより適切でしょうか? – tomseidel1

関連する問題