web-dev-qa-db-ja.com

ompordered句はどのように機能しますか?

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);
    }

これにより、vnサイズの順序付きリストで埋められます。

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

また、ordered句をdynamic scheduleと一緒に使用することが提案されているのはなぜですか? static scheduleはパフォーマンスに影響しますか?

18
Mihai Neacsu

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)を使用すると、各スレッドに割り当てられた反復のリストが非決定論的であるため、上記の画像は多かれ少なかれランダムになります。また、オーバーヘッドが追加されます。計算量が反復ごとに異なり、動的スケジューリングを使用する場合の追加のオーバーヘッドよりも計算に時間がかかる場合にのみ役立ちます。

最小の反復回数について心配する必要はありません。通常、コードを実行する準備ができるようになるために、チームの最初のスレッドに処理されます。

44
Hristo Iliev