4

OpenMPのやり方に合うように思考を調整するのに苦労しています。

大まかに言って、私が欲しいのは:

for(int i=0; i<50; i++)
{
   doStuff();
   thread t;
   t.start(callback(i)); //each time around the loop create a thread to execute callback
}

これがc++11でどのように行われるかはわかっていると思いますが、OpenMPで同様のことを実行できる必要があります。

4

2 に答える 2

10

必要なものに最も近いのはOpenMPタスクであり、OpenMPv3.0以降に準拠したコンパイラーで使用できます。それは次のようになります:

#pragma omp parallel
{
    #pragma omp single
    for (int i = 0; i < 50; i++)
    {
        doStuff();
        #pragma omp task
        callback(i);
    }
}

このコードは、ループを1つのスレッドでのみ実行しcallback()、さまざまなパラメーターで呼び出す50のOpenMPタスクを作成します。次に、すべてのタスクが終了するのを待ってから、並列領域を終了します。タスクは、実行されるアイドル状態のスレッドによって(おそらくランダムに)選択されます。OpenMPは、フォーク結合実行モデルがメインスレッドのみが並列領域の外側で実行されることを要求しているため、各並列領域の終わりに暗黙のバリアを課します。

サンプルプログラムは次のとおりです(ompt.cpp):

#include <stdio.h>
#include <unistd.h>
#include <omp.h>

void callback (int i)
{
   printf("[%02d] Task stated with thread %d\n", i, omp_get_thread_num());
   sleep(1);
   printf("[%02d] Task finished\n", i);
}

int main (void)
{
   #pragma omp parallel
   {
      #pragma omp single
      for (int i = 0; i < 10; i++)
      {
         #pragma omp task
         callback(i);
         printf("Task %d created\n", i);
      }
   }
   printf("Parallel region ended\n");

   return 0;
}

コンパイルと実行:

$ g++ -fopenmp -o ompt.x ompt.cpp
$ OMP_NUM_THREADS=4 ./ompt.x
Task 0 created
Task 1 created
Task 2 created
[01] Task stated with thread 3
[02] Task stated with thread 2
Task 3 created
Task 4 created
Task 5 created
Task 6 created
Task 7 created
[00] Task stated with thread 1
Task 8 created
Task 9 created
[03] Task stated with thread 0
[01] Task finished
[02] Task finished
[05] Task stated with thread 2
[04] Task stated with thread 3
[00] Task finished
[06] Task stated with thread 1
[03] Task finished
[07] Task stated with thread 0
[05] Task finished
[08] Task stated with thread 2
[04] Task finished
[09] Task stated with thread 3
[06] Task finished
[07] Task finished
[08] Task finished
[09] Task finished
Parallel region ended

タスクは、作成されたのと同じ順序で実行されないことに注意してください。

GCCは、4.4より古いバージョンのOpenMP3.0をサポートしていません。認識されないOpenMPディレクティブは黙って無視され、結果の実行可能ファイルはシリアルでそのコードセクションになります。

$ g++-4.3 -fopenmp -o ompt.x ompt.cpp
$ OMP_NUM_THREADS=4 ./ompt.x
[00] Task stated with thread 3
[00] Task finished
Task 0 created
[01] Task stated with thread 3
[01] Task finished
Task 1 created
[02] Task stated with thread 3
[02] Task finished
Task 2 created
[03] Task stated with thread 3
[03] Task finished
Task 3 created
[04] Task stated with thread 3
[04] Task finished
Task 4 created
[05] Task stated with thread 3
[05] Task finished
Task 5 created
[06] Task stated with thread 3
[06] Task finished
Task 6 created
[07] Task stated with thread 3
[07] Task finished
Task 7 created
[08] Task stated with thread 3
[08] Task finished
Task 8 created
[09] Task stated with thread 3
[09] Task finished
Task 9 created
Parallel region ended
于 2012-06-25T08:37:17.207 に答える
0

たとえば、http://en.wikipedia.org/wiki/OpenMPを参照してください。

#pragma omp for

あなたの友だちです。OpenMPでは、スレッドについて考える必要はありません。並行して実行したいものを宣言(!)するだけで、OpenMP互換コンパイラーがコンパイル時にコードで必要な変換を実行します。

OpenMPの仕様も非常に充実しています。彼らは何ができるか、そしてどのようにできるかを非常によく説明しています:http: //openmp.org/wp/openmp-specifications/

サンプルは次のようになります。

#pragma omp parallel for
for(int i=0; i<50; i++)
{
   doStuff();
   thread t;
   t.start(callback(i)); //each time around the loop create a thread to execute callback
}

forループ内のすべてが並行して実行されます。データの依存関係に注意を払う必要があります。'doStuff()'関数は、擬似コードで順次実行されますが、私のサンプルでは並行して実行されます。また、どの変数がスレッドプライベートであるか、および#pragmaステートメントにも含まれるようなものを指定する必要があります。

于 2012-06-25T06:57:22.230 に答える