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
ブロックに到達すると、すべてのスレッドは可能な限り低い反復のスレッドが終了するのを待つ必要がありますが、その特定の反復が指定されたスレッドがない場合はどうなりますか?または、OpenMPランタイムライブラリは常に、最低の反復が何らかのスレッドによって処理されることを確認しますか?
また、ordered
句をdynamic schedule
と一緒に使用することが提案されているのはなぜですか? static schedule
はパフォーマンスに影響しますか?
ordered
句は次のように機能します。異なるスレッドはordered
領域に遭遇するまで同時に実行され、その後、シリアルループで実行されるのと同じ順序で順番に実行されます。これにより、特にordered
領域外のコードセクションの実行時間がかなり長い場合は、ある程度の同時実行が可能になります。
チャンクサイズが小さいdynamic
スケジュールの代わりにstatic
スケジュールを使用する特別な理由はありません。それはすべてコードの構造に依存します。 ordered
はスレッド間の依存関係を導入するため、デフォルトのチャンクサイズでschedule(static)
と一緒に使用すると、2番目のスレッドは最初のスレッドがすべての反復を完了するのを待つ必要があります。 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)
を使用すると、各スレッドに割り当てられた反復のリストが非決定論的であるため、上記の画像は多かれ少なかれランダムになります。また、オーバーヘッドが追加されます。計算量が反復ごとに異なり、動的スケジューリングを使用する場合の追加のオーバーヘッドよりも計算に時間がかかる場合にのみ役立ちます。
最小の反復回数について心配する必要はありません。通常、コードを実行する準備ができるようになるために、チームの最初のスレッドに処理されます。