OpenMP での配列削減の解決
OpenMP では、配列の直接削減はサポートされていません。ただし、同様の結果を達成するための代替メソッドが存在します。
最初のメソッド:
1 つのアプローチには、スレッドごとに配列のプライベート コピーを作成し、ローカルで縮小することが含まれます。並列セクションの後で、データ競合を防ぐためにクリティカル セクションを使用してプライベート配列を元の配列にマージします。
int S[10] = {0}; #pragma omp parallel { int S_private[10] = {0}; #pragma omp for for (int n = 0; n < 10; ++n) { for (int m = 0; m <= n; ++m) { S_private[n] += A[m]; } } #pragma omp critical { for (int n = 0; n < 10; ++n) { S[n] += S_private[n]; } } }
2 番目の方法:
別の方法は次のとおりです。配列サイズにスレッド数を乗算したものと等しい次元を持つ、より大きな配列を割り当てます。その後、各スレッドが配列のその部分を埋めます。並列セクションの後で、クリティカル セクションを使用せずに値を元の配列にマージします。
int S[10] = {0}; int *S_private; #pragma omp parallel { const int nthreads = omp_get_num_threads(); const int ithread = omp_get_thread_num(); #pragma omp single { S_private = new int[10 * nthreads]; for (int i = 0; i < (10 * nthreads); i++) { S_private[i] = 0; } } #pragma omp for for (int n = 0; n < 10; ++n) { for (int m = 0; m <= n; ++m) { S_private[ithread * 10 + n] += A[m]; } } #pragma omp for for (int i = 0; i < 10; i++) { for (int t = 0; t < nthreads; t++) { S[i] += S_private[10 * t + i]; } } }
2 番目の方法は、特に複数のソケットが関与するシナリオではより効率的ですが、メモリの誤動作を避けるために慎重なメモリ処理も必要になります。キャッシュの問題。
以上がOpenMP で配列の削減を効率的に実行するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。