これら2つの違いは何ですか?
[A]
#pragma omp parallel
{
#pragma omp for
for(int i = 1; i < 100; ++i)
{
...
}
}
[B]
#pragma omp parallel for
for(int i = 1; i < 100; ++i)
{
...
}
違いはないと思います。1つは他のショートカットです。ただし、実際の実装ではそれらの処理方法が異なる場合があります。
結合された並列ワークシェアリング構造は、1つのワークシェアリング構造を含み、他のステートメントを含まない並列構造を指定するためのショートカットです。許可された条項は、並列およびワークシェアリングの接続に許可された条項の結合です。
http://www.openmp.org/mp-documents/OpenMP3.0-SummarySpec.pdf から取得
OpenMPの仕様は次のとおりです。
これらは同等です。
#pragma omp parallel
はスレッドのグループを生成し、#pragma omp for
は生成されたスレッド間でループの繰り返しを分割します。融合#pragma omp parallel for
ディレクティブを使用すると、両方を同時に実行できます。
以下に、分離されたparallel
とfor
here の使用例を示します。つまり、複数のスレッドでfor
サイクルを実行する前に、OpenMPスレッドプライベート配列の動的割り当てに使用できます。 parallel for
の場合に同じ初期化を行うことは不可能です。
UPD:質問の例では、単一のプラグマと2つのプラグマの間に違いはありません。しかし、実際には、分離された並列ディレクティブとforディレクティブを使用して、スレッドを認識する動作を強化できます。たとえば、いくつかのコード:
#pragma omp parallel
{
double *data = (double*)malloc(...); // this data is thread private
#pragma omp for
for(1...100) // first parallelized cycle
{
}
#pragma omp single
{} // make some single thread processing
#pragma omp for // second parallelized cycle
for(1...100)
{
}
#pragma omp single
{} // make some single thread processing again
free(data); // free thread private data
}
特定の例の両方のバージョンは同等ですが、他の回答で既に述べたように、それらの間にはまだ1つの小さな違いがあります。最初のバージョンには、「omp for」の最後にある不要な暗黙のバリアが含まれています。他の暗黙的なバリアは、並列領域の終わりにあります。 「nowait」を「omp for」に追加すると、少なくともOpenMPの観点からは、2つのコードが同等になります。これは、OpenMPコンパイラーが2つのケースでわずかに異なるコードを生成する可能性があるためです。
G ++ 4.7.0でforループを使用して使用すると、まったく異なるランタイムが表示されます
std::vector<double> x;
std::vector<double> y;
std::vector<double> prod;
for (int i = 0; i < 5000000; i++)
{
double r1 = ((double)Rand() / double(Rand_MAX)) * 5;
double r2 = ((double)Rand() / double(Rand_MAX)) * 5;
x.Push_back(r1);
y.Push_back(r2);
}
int sz = x.size();
#pragma omp parallel for
for (int i = 0; i< sz; i++)
prod[i] = x[i] * y[i];
シリアルコード(openmp
なし)は79ミリ秒で実行されます。 「for for」コードは29ミリ秒で実行されます。 for
を省略して#pragma omp parallel
を使用すると、ランタイムは最大179msになり、シリアルコードよりも遅くなります。 (マシンのハードウェア同時実行数は8です)
コードはlibgomp
にリンクします
明らかにたくさんの答えがありますが、これは非常にうまく答えています(ソース付き)
#pragma omp for
は、現在のチーム内の異なるスレッドのループ部分のみを委任します。チームは、プログラムを実行するスレッドのグループです。プログラムの開始時には、チームは単一のメンバー、つまりプログラムを実行するマスタースレッドのみで構成されています。スレッドの新しいチームを作成するには、parallelキーワードを指定する必要があります。周囲のコンテキストで指定できます:
#pragma omp parallel { #pragma omp for for(int n = 0; n < 10; ++n) printf(" %d", n); }
そして:
概要:パラレル、チーム、チーム
並列、並列forおよびforの違いは次のとおりです。
チームとは、現在実行されているスレッドのグループです。プログラムの開始時、チームは単一のスレッドで構成されています。並列構造は、次のブロック/ステートメントの期間中に現在のスレッドをスレッドの新しいチームに分割し、その後チームは1つにマージします。 forは、forループの作業を現在のチームのスレッド間で分割します。
スレッドを作成するのではなく、現在実行中のチームのスレッド間で作業を分割するだけです。 parallel forは、2つのコマンド(parallelとfor)の省略形です。 Parallelは新しいチームを作成し、そのチームを分割してループのさまざまな部分を処理します。プログラムに並列構造が含まれない場合、複数のスレッドが存在することはありません。非スレッドプログラムのように、プログラムを起動して実行するマスタースレッド。