OpenMP での配列の削減
OpenMP は、広範囲のアプリケーションに並列実行機能を提供します。ただし、OpenMP では直接サポートされていない配列削減に関してよくある質問が生じます。
代替ソリューション
ネイティブの配列削減は利用できませんが、代替方法があります。 C/C で同様の機能を実現するには:
方法 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: スレッド ローカル配列の削減
この方法では、次元 10*nthread の中間配列を作成することでクリティカル セクションを削除します。スレッドはこの配列を並列で埋めてから、元の配列にマージします。
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]; } } } delete[] S_private;
これらのアプローチにより、OpenMP のネイティブ配列削減の欠如が克服され、並列で配列要素を効率的に蓄積できるようになります。
以上が直接サポートされていない場合、OpenMP で配列の削減をどのように実現できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。