ホームページ >バックエンド開発 >C++ >直接サポートされていない場合、OpenMP で配列の削減をどのように実現できますか?

直接サポートされていない場合、OpenMP で配列の削減をどのように実現できますか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-12-04 07:00:12692ブラウズ

How Can Array Reduction Be Achieved in OpenMP When It's Not Directly Supported?

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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。