1

私は、以下の回路図を持つ計算コードを書いています。

#pragma omp parallel
{
    #pragma omp for nowait
    // Compute elements of some array A[i] in parallel

    #pragma omp single
    for (i = 0; i < N; ++i) {
        // Do some operation with A[i].
        // This time it is important that operations are sequential. e.g.:
        result = compute_new_result(result, A[i]);
    }
}

コンピューティングA[i]とどちらcompute_new_resultもかなり高価です。したがって、私の考えは、配列要素を並列に計算し、いずれかのスレッドが解放されると、順次操作を開始することです。開始配列要素がすでに計算されている可能性が高く、他の要素はまだ最初のループを実行している他のスレッドによって提供されます。

ただし、コンセプトを機能させるには、次の 2 つのことを達成する必要があります。

  1. OpenMP が別の方法でループを分割するようにするには、つまり 2 つのスレッドに対して: 、 を計算するスレッド 1 、およびA[0]、を計算するスレッド 2: 、、など。A[2]A[4]A[1]A[3]A[5]

  2. 信号システムを提供するため。A[i]すでに計算されていることを示すフラグの配列について考えています。次に、続行する前にcompute_new_result、それぞれのフラグが解放されるのを待つ必要があります。A[i]

両方の目標を達成するためのヒントをいただければ幸いです。Linux、Windows、Mac 間で移植できるソリューションが必要です。コード全体を C++11 で書いています。


編集:

私は最初の質問に対する答えを見つけました。ディレクティブにschedule(static,1)句を追加するだけで十分なようです。#pragma omp for

ただし、2番目の問題のエレガントな解決策についてはまだ考えています...

4

2 に答える 2

1

ワークシェアリング用の OpenMP コンストラクトを代わりにタスクを生成するループに置き換えても構わない場合は、OpenMP タスクを使用してアプリケーションの両方の部分を実装できます。

最初のループでは、(ループ チャンクの代わりに) 反復の計算負荷を引き受けるタスクを作成します。2 番目のループの各反復も OpenMP タスクになります。重要な部分は、異なるフェーズ間でタスクを同期させることです。

そのために、タスクの依存関係を使用できます (OpenMP 4.0 で導入):

#pragma omp task depend(out:A[0])
{ A[0] = a(); }

#pragma omp task depend(in:A[0])
{ b(A[0]); }

タスク a が完了する前にタスク b が実行されないようにします。

乾杯 - マイケル

于 2013-10-02T19:33:57.947 に答える
0

これはおそらく回答ではなく拡張コメントです...

したがって、2 フェーズの計算が行われます。フェーズ 1 では、配列内の各エントリを個別に計算できますAparallel forしたがって、OpenMPループを使用してこれを並列化するのは簡単です。しかし、ここで問題があります。スレッドへの単純な作業の割り当ては、スレッド間で (深刻な?) 不均衡な負荷につながる可能性があります。

フェーズ 2 には、簡単には並列化できない計算があり、フェーズ 1 の分担を完了するために最初のスレッドに渡す予定です。

個人的には、これを 2 つのフェーズに分けます。最初に、parallel forループを使用します。2 番目のドロップでは OpenMP を使用し、シーケンシャル コードのみを使用します。schedule句に対する引数を調整することにより、フェーズ 1 内の負荷分散を整理します。schedule(guided)最初に試してみたくなります。

スケジュールを調整しても必要なバランスが得られない場合は、parallel for-ingtaskで置き換えることを検討してください。

独自のシグナリング手法を使用して、フェーズ 2 のコードを複雑にしないでください。あなたはそれについて心配しているかもしれませんが、合併症があなたを圧倒することは心配していませんが、フェーズ1で負荷バランスを整理しない限り、合併症は何の利益ももたらさないでしょう. ' Phase2 を OpenMP 並列領域内に配置する必要はありません。

于 2013-10-02T12:25:28.547 に答える