ホームページ > バックエンド開発 > C++ > OpenMP 並列 for ループを使用する場合、特にサイズ変更が必要な場合、`std::vector` に代わる効率的な代替手段は何ですか?

OpenMP 並列 for ループを使用する場合、特にサイズ変更が必要な場合、`std::vector` に代わる効率的な代替手段は何ですか?

Susan Sarandon
リリース: 2024-11-29 08:03:09
オリジナル
490 人が閲覧しました

What are the efficient alternatives to `std::vector` when using OpenMP parallel for loops, especially when resizing is needed?

OpenMP 並列 For ループの std::vector の代替

OpenMP では、並列 for ループで共有 std::vector を操作します。ループはパフォーマンス上の問題を引き起こす可能性があります。この記事では、特にループの実行中にサイズ変更が必要な場合に、速度上の利点を提供する潜在的な代替案を検討します。

候補代替案

  • std OpenMP を使用した ::vector Reduction:

    このアプローチには、#pragma omp Declaredduction で宣言されたユーザー定義のリダクションの使用が含まれます。以下のコードは、ベクトルを並列に結合するためにどのように適用できるかを示しています:

    #pragma omp declare reduction (merge : std::vector<int> : omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end()))
    
    std::vector<int> vec;
    #pragma omp parallel for reduction(merge: vec)
    for (int i = 0; i < 100; i++) vec.push_back(i);
    ログイン後にコピー
  • 静的スケジューリングと順序付けされた挿入を備えた std::vector:

    要素の順序を保持することが重要な場合は、この手法を使用できます。静的スケジュールと順序付きセクションを利用して、目的のシーケンスにベクトルを挿入します。

    std::vector<int> vec;
    #pragma omp parallel
    {
        std::vector<int> vec_private;
        #pragma omp for nowait schedule(static)
        for (int i = 0; i < N; i++) vec_private.push_back(i);
        #pragma omp for schedule(static) ordered
        for (int i = 0; i < omp_get_num_threads(); i++)
        {
            #pragma omp ordered
            vec.insert(vec.end(), vec_private.begin(), vec_private.end());
        }
    }
    ログイン後にコピー
  • Prefix Sum メソッド:

    このメソッドスレッドごとにベクトルを保存することを回避し、並列にマージされた単一のベクトルを選択します。プレフィックス合計配列を利用して挿入ポイントを追跡します。

    std::vector<int> vec;
    size_t *prefix;
    #pragma omp parallel
    {
        int ithread = omp_get_thread_num();
        int nthreads = omp_get_num_threads();
        #pragma omp single
        {
            prefix = new size_t[nthreads + 1];
            prefix[0] = 0;
        }
        std::vector<int> vec_private;
        #pragma omp for schedule(static) nowait
        for (int i = 0; i < 100; i++) vec_private.push_back(i);
        prefix[ithread + 1] = vec_private.size();
        #pragma omp barrier
        #pragma omp single
        {
            for (int i = 1; i < (nthreads + 1); i++) prefix[i] += prefix[i - 1];
            vec.resize(vec.size() + prefix[nthreads]);
        }
        std::copy(vec_private.begin(), vec_private.end(), vec.begin() + prefix[ithread]);
    }
    delete[] prefix;
    ログイン後にコピー

これらの代替手段は、制限を超えて、OpenMP 環境で並列 for ループを操作し、ベクトルのサイズを変更するための効果的かつ効率的な手段を提供します。 std::vector.

によって提示されます。

以上がOpenMP 並列 for ループを使用する場合、特にサイズ変更が必要な場合、`std::vector` に代わる効率的な代替手段は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート