0

OpenMP で for ループを並列化しようとしています。通常、これはかなり簡単です。ただし、for ループを実行する前に、スレッド固有の初期化を実行する必要があります。

具体的には、次の問題があります。スレッドセーフではない乱数ジェネレーターがあるため、スレッドごとに RNG のインスタンスを作成する必要があります。しかし、すべてのスレッドが同じ乱数を生成するわけではないことを確認したいと思います。

だから私は次のことを試しました:

    #pragma omp parallel
    {
        int rndseed = 42;
        #ifdef _OPENMP
            rndseed += omp_get_thread_num();
        #endif

         // initialize randon number generator

         #pragma omp for
         for (int sampleid = 0; sampleid < numsamples; ++sampleid)
         {
             // do stuff
         }
    }

この構成を使用すると、実行時に次のエラー メッセージが表示されます。

致命的なユーザー エラー 1002: '#pragma omp for' がワークシェアリング構造に不適切にネストされている

スレッド固有の初期化を行う方法はありますか?

ありがとう

4

2 に答える 2

0

あなたが持っているエラー:

Fatal User Error 1002: '#pragma omp for' improperly nested in a work-sharing construct

ワークシェアリング コンストラクトの不正なネストを参照します。実際、OpenMP 3.1 標準では、セクション 2.5 で次の制限が設けられています。

  • 各ワークシェアリング リージョンは、チーム内のすべてのスレッドによって検出されるか、またはまったく検出されない必要があります。
  • 遭遇するワークシェアリング領域とバリア領域の順序は、チーム内のすべてのスレッドで同じでなければなりません。

上で引用した行から、同じ並列領域内に異なるワークシェアリング構造をネストすることは準拠していないことがわかります。

あなたのスニペットでは違法なネストは見えませんが、実際のコードに関して投稿を単純化しすぎて隠されていると思います。ヒントを与えるために、最も一般的なケースは次のとおりです。

  • 単一の構造内にネストされたループ ワークシェアリング構造 (ここの例と同様)
  • 別のループ構造内にネストされたループ ワークシェアリング構造

興味がある場合は、この回答で後者のケースについて詳しく説明します。

于 2013-06-17T19:14:06.827 に答える
0

設計ミスだと思います。

並列 for ループは、たとえばコア数が N の N スレッドだけではなく、1 <= N*X < numsamples の N*X スレッドになる可能性もあります。

「反復プライベート」変数が必要な場合は、ループ本体のすぐ内側で宣言します(ただし、すでに知っています)。しかし、並列 for ループ内で使用するスレッド プライベート変数を宣言することは、おそらく十分に正当化されません。

于 2013-06-17T10:45:58.890 に答える