0

これが以前に尋ねられた場合は申し訳ありませんが、見つけることができませんでした。それは簡単な質問です。各スレッドが for ループ内のすべてのステートメントを実行するように OpenMP を使用しようとしています。

例: 2 つの CPU があり、2 つのスレッドを使用しているとします。

#pragma omp for schedule(dynamic) 
    for(int n=0; n<n_size; ++n) { 
foo1();
foo2();
}

Thread[1] で foo1() と foo2() を順次処理し、Thread[2] で別の反復を処理しますが、foo1() と foo2() などを使用します。for文を宣言した直後にセクションを使おうとしたのですが、プログラムが緩んでしまいました。

どんな助けでも大歓迎です。

乾杯、-ラウィ

######################################################

以下のコメントと議論の後、簡単なプログラムを提供します。

// put inside main()
int k;
#pragma omp parallel num_threads(2)
    {
#pragma omp for schedule(dynamic) // or using this: schedule(dynamic); I don't know which one is faster
        for( int n=0; n<4; ++n) {
 // #pragma omp single
            { k=0;
                foo1(k);
                foo2(k);
            }
        }

    }

// main ends here

// foo1 increments k which is passed as a reference, then prints it, then, foo2, increments k. So the upper value should be 2. Here's how they look like:
void foo1(int &n){
    cout<<"calling foo1"<<" k= "<<n<<" T["<<omp_get_thread_num()<<endl;
    ++n;

}

void foo2(int &n){
    cout<<"calling foo2"<<" k= "<<n<<" T["<<omp_get_thread_num()<<endl;
    ++n;
}

出力は次のとおりです。

calling foo1 k= calling foo1 k= 0 T[00 T[1
calling foo2 k= 1 T[0
calling foo1 k= 0 T[0
calling foo2 k= 1 T[0

calling foo2 k= 2 T[1
calling foo1 k= 0 T[1
calling foo2 k= 1 T[1

ご覧のとおり、foo2 の T[1] の k は 3 でしたが、1 である必要があります。

なぜこのエラーが発生するのですか? foo2 は、foo1 によって検出された値に依存します (私のアプリケーションでは、実際のパラメーターが関数に渡されます)。

それで、「#pragma omp single」を使用すると少しは役に立ちましたが、これを入れ子にするべきではないというコメントがありました! 「#pragma omp single」を使用した後の出力は次のとおりです。

calling foo1 k= 0 T[0
calling foo2 k= 1 T[0
calling foo1 k= 0 T[1
calling foo2 k= 1 T[1

ただし、さらに 4 つの出力 (奇数の n 値) が必要ですか?

4

1 に答える 1

0

for ループを並列化するのではなく、並列領域内に配置します。

#pragma omp parallel
{
  for(int n=0; n<n_size; ++n)  // every thread will run all iterations
  { 
    foo1();
    foo2();
  }
  // threads are not synchronised here! (no implicit barrier)
}
于 2013-10-01T15:52:19.447 に答える