#pragma omp for schedule(static)
チャンク サイズが指定されていない場所 についていくつか質問があります。
OpenMP でループを並列化する 1 つの方法は、次のように手動で行うことです。
#pragma omp parallel
{
const int nthreads = omp_get_num_threads();
const int ithread = omp_get_thread_num();
const int start = ithread*N/nthreads;
const int finish = (ithread+1)*N/nthreads;
for(int i = start; i<finish; i++) {
//
}
}
OpenMP でこのようなループを手動で並列化しない正当な理由はありますか? 値を と比較すると、特定のスレッドのチャンク サイズが常に一致するとは限らないため、OpenMP (GCC 内) はおよび#pragma omp for schedule(static)
で定義されているものとは異なるチャック サイズを実装していることがわかります。どうしてこれなの?start
finish
私が定義したstart
とのfinish
値には、いくつかの便利なプロパティがあります。
- 各スレッドは、最大で 1 つのチャンクを取得します。
- 反復の値の範囲は、スレッド数に比例して増加します (つまり、2 つのスレッドを持つ 100 スレッドの場合、最初のスレッドは 1 ~ 50 の反復を処理し、2 番目のスレッドは 51 ~ 100 の反復を処理し、その逆ではありません)。
- まったく同じ範囲の 2 つの for ループの場合、各スレッドはまったく同じ反復で実行されます。
編集:元は正確に1つのチャンクと言いましたが、考えてみると、スレッドの数がN
(ithread*N/nthreads = (ithread*1)*N/nthreads
)よりもはるかに大きい場合、チャンクのサイズがゼロになる可能性があります。私が本当に欲しいプロパティは、せいぜい 1 つのチャンクです。
を使用すると、これらすべてのプロパティが保証され#pragma omp for schedule(static)
ますか?
OpenMP 仕様によると:
他の状況下で特定の反復を実行するスレッドに依存するプログラムは、非準拠です。
と
同じ並列領域で発生した場合でも、スケジュールと反復回数が同じ異なるループ領域は、スレッド間で異なる方法で反復配分を分配できます。唯一の例外は静的スケジュールです。
schedule(static)
仕様については次のように述べています。
チャンクは、チーム内のスレッドにスレッド番号順にラウンドロビン方式で割り当てられます。
さらに、仕様は `schedule(static) について次のように述べています。
chunk_size が指定されていない場合、反復スペースはほぼ同じサイズのチャンクに分割され、最大で 1 つのチャンクが各スレッドに分散されます。
最後に、仕様は次のように述べていschedule(static)
ます。
準拠する静的スケジュールの実装では、次の条件が満たされる場合、2 つのループ領域でスレッドへの論理反復番号の同じ割り当てが使用されるようにする必要があります。領域に同じ値の chunk_size が指定されているか、両方のループ領域に chunk_size が指定されていません。3) 両方のループ領域が同じ並列領域にバインドされています。
したがって、これを正しく読むと、リストしたのとschedule(static)
同じ便利なプロパティが あり、コードがスレッドに依存していても、特定の反復が実行されます。 これを正しく解釈できますか?これは、チャンク サイズが指定されていない 場合の特殊なケースのようです。start
finish
schedule(static)
定義するだけの方が簡単で、私がstart
しfinish
たように、この場合の仕様を中断しようとしました。