2016-05-03 7 views
0

ホテルトップとのOpenMPスレッド

omp_set_num_threads(20); 

20件のスレッド(利用可能な40個のスレッドを持っている)を使用するのOpenMPを伝えます。 (まだそうでないかもしれない最良の方法はなく)forループの主のための

#pragma omp parallel for shared(x,y,z) 

、およびホテルトップ介してCPU使用率を監視します。

私は、ディレクティブが含まれている私のコードを実行します。 forループが実行しなければならない50個の "タスク"があり、それぞれかなりの時間がかかります。私がhtopを通して観察していることは、タスクが完了した後、スレッド数が減少することです。具体的には、20スレッドを使用すると、20スレッド以下のタスクが残ってからスレッドが「フリー」になるまで、edは2000%のCPU使用率を見ています。しかし、私が見ているのは最初の2000%であり、n個のタスクが完了した後、私は2000% - (n * 100%)のパフォーマンスを見ます。したがって、タスクが完了すると、新しいタスクを実行するのではなく、スレッドがシャットダウンするように見えます。

これは予期されるのか、それとも奇妙なのでしょうか?

+0

20タスク後にCPU使用率がゼロになり、並列ループは終了しませんか? –

+0

いいえ、終了します。私の質問は、処理が必要なタスクがまだ存在するときにスレッドが死んでしまうように見える理由です。 – user1938803

+1

50を20で割った値が2.5で、ほとんどのコンパイラでのデフォルトのループスケジューリングが 'static'なので、スレッドの半分は2回の反復を処理し、残りの半分は3回の反復を処理します。 –

答えて

1

ほとんどすべての既存のOpenMPコンパイラのデフォルトの並列ループスケジューリングはstaticです。つまり、OpenMPランタイムはスレッド間でイテレーション空間を均等に分割し、静的な作業割り当てを試みます。 50の反復と20のスレッドがあるので、20を50に分割しないので、ワークを均等に分割することはできません。したがって、スレッドの半分は3回の反復を行い、残りの半分は2回の反復を行います。

parallelforコンストラクションの最後に暗黙的なバリアがあり、先に完了したスレッドが残りのスレッドを完了するのを待ちます。 OpenMPの実装によっては、ビジー待機ループ、一部のOS同期オブジェクトの待機操作、またはその両方の組み合わせとして障壁が実装される可能性があります。後者の2つのケースでは、障壁に衝突したスレッドのCPU使用率は、割り込み可能なスリープ状態に入ると直ちにゼロに低下するか、または短時間(ビジーループ)100%待つ)。

ループの反復で正確に同じ時間がかかる場合、CPU使用率は最初は2000%、その後は2回反復されます(バリア実装で短いビジーループが使用されている場合はもう少しです) 1000%に低下します。反復にそれぞれ異なる時間がかかる場合、スレッドは障壁の異なる瞬間に到着し、CPU使用率は徐々に低下します。

いずれの場合も、schedule(dynamic)を使用して、最初のスレッドに与えられた各繰り返しを利用可能にします。これにより、繰り返しに時間がかかっている場合のCPU使用率が向上します。反復で同じ時間がかかる場合は役に立ちません。後者の場合の解決策は、スレッド数の整数倍の反復回数を持つことです。