回答:
違いはないと思います。1つはもう1つのショートカットです。あなたの正確な実装はそれらを異なって扱うかもしれませんが。
組み合わせた並列ワークシェアリング構成は、1つのワークシェアリング構成を含み他のステートメントを含まない並列構成を指定するためのショートカットです。許可された条項は、並行およびワークシェアリング契約に許可された条項の和集合です。
http://www.openmp.org/mp-documents/OpenMP3.0-SummarySpec.pdfから取得
OpenMPの仕様は次のとおりです。
これらは同等です。
#pragma omp parallel
スレッドのグループを#pragma omp for
生成し、生成されたスレッド間でループ反復を分割します。fuse #pragma omp parallel for
ディレクティブを使用すると、両方を一度に実行できます。
#pragma omp parallel for
ディレクティブを使用しても同じことがうまくいきます。いくつかの違いがあるはずです。
これは分離された使用例parallel
とfor
ここです。つまり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
}
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ミリ秒で実行されます。「並列」コードは29ミリ秒で実行されます。省略した場合for
を使用した#pragma omp parallel
場合、ランタイムは最大179msを撮影します。これはシリアルコードよりも低速です。(マシンのハードウェア同時実行数は8です)
コードのリンク先 libgomp
#pragma omp for
、ループがないとマルチスレッドでループを共有できないためです。とにかく、それはOPのケースではありませんでした。#pragma omp for
内部に追加で再試行してください。バージョン#pragm omp parallel
と同じように実行されます(同じでない場合)#pragma omp parallel for
。
明らかにたくさんの答えがありますが、これは非常にうまく答えます(ソース付き)
#pragma omp for
現在のチームの異なるスレッドにループの一部のみを委任します。チームは、プログラムを実行するスレッドのグループです。プログラムの開始時、チームは単一のメンバー(プログラムを実行するマスタースレッド)のみで構成され ています。スレッドの新しいチームを作成するには、parallelキーワードを指定する必要があります。周囲のコンテキストで指定できます。
#pragma omp parallel { #pragma omp for for(int n = 0; n < 10; ++n) printf(" %d", n); }
そして:
何が:並列、for、チーム
parallel、parallel for、forの違いは次のとおりです。
チームは、現在実行されているスレッドのグループです。プログラムの開始時、チームは単一のスレッドで構成されています。並列構造は、次のブロック/ステートメントの期間中、現在のスレッドを新しいスレッドのチームに分割し、その後、チームは1つにマージされます。forループの作業を現在のチームのスレッド間で分割します。
スレッドは作成されません。現在実行中のチームのスレッド間で作業が分割されるだけです。parallel forは、2つのコマンドを一度に簡略化したものです。Parallelは新しいチームを作成し、そのチームを分割してループのさまざまな部分を処理します。プログラムに並列構造が含まれていない場合、スレッドは1つしかありません。非スレッドプログラムと同様に、プログラムを開始して実行するマスタースレッド。
schedule(static, chunk)
、forディレクティブで句を使用すると、問題が発生します。コードは問題なく実行されますが、MPIプログラムからこのコードを呼び出すと、無限ループに陥ります。ループカウンターは、このループのすべての反復でゼロです。ループカウンターを#pragma omp parallel
ディレクティブでプライベートとして定義しています。MPIがコードを呼び出すときにのみ失敗する理由はわかりません。問題がある場合は、各MPIプロセスがクラスターの異なるプロセッサで実行されていることをいくらか確信しています。スケジュールが問題の原因かどうかはわかりません。