2012-11-04 10 views
11
vector<int> v; 

#pragma omp parallel for ordered schedule(dynamic, anyChunkSizeGreaterThan1) 
    for (int i = 0; i < n; ++i){ 
      ... 
      ... 
      ... 
#pragma omp ordered 
      v.push_back(i); 
    } 

vには、nのサイズ順リストが入っています。omp ordered句はどのように機能しますか?

omp orderedブロックに達すると、すべてのスレッドは最小の反復可能スレッドが完了するのを待つ必要がありますが、特定の繰り返しがスレッドに割り当てられていない場合はどうなりますか?または、OpenMPランタイムライブラリは、常に最小の反復があるスレッドによって処理されることを確認していますか?

また、dynamic scheduleと一緒にordered節を使用することをお勧めしますか? static scheduleはパフォーマンスに影響しますか?

答えて

31

ordered句は、ordered領域に出会うまで並行して実行され、シリアルループで実行されるのと同じ順序で順次実行されます。特に、ordered領域外のコードセクションにかなりの実行時間がある場合は、これにより、ある程度の並行性が可能になります。

小さいチャンクサイズのstaticスケジュールの代わりにdynamicスケジュールを使用する特別な理由はありません。それはすべてコードの構造に依存します。 orderedはスレッド間で依存関係が導入されているので、デフォルトチャンクサイズのschedule(static)で使用すると、2番目のスレッドは最初のスレッドがすべての繰り返しを終了するまで待機し、3番目のスレッドは2番目のスレッドが繰り返しを終了するまで待機する必要があります従って最初のものについても)、等々。一つは、簡単に3つのスレッドと9回の反復(スレッド当たり3)でそれを可視化することができ:

tid List of  Timeline 
    iterations 
0 0,1,2  ==o==o==o 
1 3,4,5  ==.......o==o==o 
2 6,7,8  ==..............o==o==o 

=スレッドが並行してコードを実行していることを示しています。 oは、スレッドがordered領域を実行しているときです。 .はアイドル状態のスレッドで、ordered領域の実行を待っています。 schedule(static,1)では、次はどうなる:

tid List of  Timeline 
    iterations 
0 0,3,6  ==o==o==o 
1 1,4,7  ==.o==o==o 
2 2,5,8  ==..o==o==o 

私は両方のケースの違いは明白よりもあると信じています。 schedule(dynamic)では、各スレッドに割り当てられた反復のリストが非決定論的なので、上記の画像は多かれ少なかれランダムになります。また、追加のオーバーヘッドが追加されます。計算の量が反復毎に異なる場合にのみ有用であり、動的スケジューリングを使用した場合のオーバーヘッドの増加よりも計算に多くの時間がかかります。

番号が最も小さい反復について心配する必要はありません。これは通常、コードを実行する準備が整うようにチームの最初のスレッドに処理されます。

+0

優秀な回答Hristo!すべて今クリアする、ありがとう! –

+2

@ Cookie503、チャンクサイズが小さすぎると、データのローカリティが失われてキャッシュが役に立たなくなることに注意してください。これは暗黙のシリアライゼーションよりもパフォーマンスが大幅に悪くなる可能性があります。最高のスピードアップが達成されるまで、さまざまなチャンクサイズで試してみてください。順序付けされたループを賢明に使用し、可能であればそれらを避けてください。 (あなたの特定の例では)ベクトルの代わりにシンプルな事前割り付け配列(または他のスレッドセーフランダムアクセスコンテナ)を使うべきです: 'arr [i] = i;' –

関連する問題