parallel for
ループ内で値を合計ため、次の簡単なコードを考えてみてください:OpenMP並列-の効率クエリ
int nMaxThreads = omp_get_max_threads();
int nTotalSum = 0;
#pragma omp parallel for num_threads(nMaxThreads) \
reduction(+:nTotalSum)
for (int i = 0; i < 4; i++)
{
nTotalSum += i;
cout << omp_get_thread_num() << ": nTotalSum is " << nTotalSum << endl;
}
私は2つのコアマシン上でこれを実行すると、私が手出力が
です0: nTotalSum is 0
0: nTotalSum is 1
1: nTotalSum is 2
1: nTotalSum is 5
これは、クリティカルセクション、つまりnTotalSum
の更新が各ループで実行されていることを示唆しています。これは無駄に思えますが、各スレッドが行う必要がある場合は、追加する値の 'ローカル'合計を計算してから、nTotalSum
をこの 'ローカル合計'に更新してから更新してください。
私の出力の解釈は正しいのですか?もしそうなら、どうすればより効率的にすることができますか?
#pragma omp parallel for num_threads(nMaxThreads) \
reduction(+:nTotalSum)
int nLocalSum = 0;
for (int i = 0; i < 4; i++)
{
nLocalSum += i;
}
nTotalSum += nLocalSum;
...しかし、コンパイラは、各OMPスレッドはnTotalSum
の独自のコピーを持っている...それはpragma omp parallel for
次の文for
ループを期待していたことを
ありがとうございます。ループの前とループ内のアドレスを出力することで、各スレッドに 'nTotalSum'のローカルコピーがあることを確認しました。予想どおり、3つの異なるアドレスがありました。ループの前と後の変数の値、および2つのスレッドのそれぞれの変数の値です。 – Wad