コードの並列部分のスレッド数を指定する方法について、私はかなり混乱しています。私は使用できることを知っています:
#pragma omp parallel for num_threads(NB_OF_THREADS)
これまでに収集したものは、最初の2つは同等です。しかし、3番目のものはどうですか?誰かが違いのより詳細な説明を提供できますか、1/2と3の違いに関する情報はインターネットで見つかりませんでした。
_OMP_NUM_THREADS
_とomp_set_num_threads()
は同等ではありません。環境変数は、チーム内のスレッドの最大数を制御するnthreads-var ICV(内部制御変数)の初期値を設定するためにのみ使用されます。 omp_set_num_threads()
を使用すると、nthreads-varの値をいつでも(もちろん、並列領域外で)変更でき、後続のすべての並列領域に影響します。したがって、値を設定します。 n
、to _OMP_NUM_THREADS
_は、最初の並列領域が検出される前にomp_set_num_threads(n)
を呼び出すことと同じです。
並列領域のスレッド数を決定するアルゴリズムは、OpenMP Webサイトで自由に入手できる OpenMP仕様 で非常に明確に説明されています。
if_
num_threads
_句が存在する場合then letThreadsRequestedは、_
num_threads
_句の式の値です。else letThreadsRequested = nthreads-varの最初の要素の値;
nthreads-varを設定するさまざまな方法の優先順位は、仕様のICVオーバーライド関係の部分にリストされています。
_
num_threads
_句とomp_set_num_threads()
は、_OMP_NUM_THREADS
_環境変数の値とnthreads-var ICVの最初の要素の初期値をオーバーライドします。
人間の言語に翻訳される、つまり:
OMP_NUM_THREADS
_(存在する場合)は、最初にスレッドの数を指定します。omp_set_num_threads()
を呼び出すと、_OMP_NUM_THREADS
_の値が上書きされます。num_threads
_句が存在すると、他の両方の値が上書きされます。使用される実際のスレッド数は、動的チームサイズが有効かどうか(dyn-var ICVが_OMP_DYNAMIC
_またはomp_set_dynamic()
を介して設定可能)かどうか、またthread-limit-var(_OMP_THREAD_LIMIT
_を介して設定可能)、およびネストされた並列処理(_OMP_NESTED
_/omp_set_nested()
)が有効かどうか。
スコープのように考えてください。オプション3(num_threads)は、スレッドの現在のチームのみのスレッド数を設定します。その他のオプションは、グローバル/状態設定です。通常はスレッド数を設定せず、デフォルトを使用します。スレッド数を変更する場合、通常は特別な場合に限られるため、次に並列チームを使用するときにグローバル(デフォルト)設定に戻るように、オプション3を使用します。以下のコードを参照してください。オプション3を使用した後、次のスレッドチームが最後のグローバル設定に戻ります。
#include <stdio.h>
#include <omp.h>
int main() {
#pragma omp parallel
{
#pragma omp single
{
printf("%d\n", omp_get_num_threads());
}
}
omp_set_num_threads(8);
#pragma omp parallel
{
#pragma omp single
{
printf("%d\n", omp_get_num_threads());
}
}
#pragma omp parallel num_threads(2)
{
#pragma omp single
{
printf("%d\n", omp_get_num_threads());
}
}
#pragma omp parallel
{
#pragma omp single
{
printf("%d\n", omp_get_num_threads());
}
}
}
4 8 2 8