web-dev-qa-db-ja.com

omp parallel vs. omp parallel for

これら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)
{
   ...
}
95
Hyunjik Bae

違いはないと思います。1つは他のショートカットです。ただし、実際の実装ではそれらの処理方法が異なる場合があります。

結合された並列ワークシェアリング構造は、1つのワークシェアリング構造を含み、他のステートメントを含まない並列構造を指定するためのショートカットです。許可された条項は、並列およびワークシェアリングの接続に許可された条項の結合です。

http://www.openmp.org/mp-documents/OpenMP3.0-SummarySpec.pdf から取得

OpenMPの仕様は次のとおりです。

https://openmp.org/specifications/

60
Ade Miller

これらは同等です。

#pragma omp parallelはスレッドのグループを生成し、#pragma omp forは生成されたスレッド間でループの繰り返しを分割します。融合#pragma omp parallel forディレクティブを使用すると、両方を同時に実行できます。

60

以下に、分離されたparallelforhere の使用例を示します。つまり、複数のスレッドで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
}
25
NtsDK

特定の例の両方のバージョンは同等ですが、他の回答で既に述べたように、それらの間にはまだ1つの小さな違いがあります。最初のバージョンには、「omp for」の最後にある不要な暗黙のバリアが含まれています。他の暗黙的なバリアは、並列領域の終わりにあります。 「nowait」を「omp for」に追加すると、少なくともOpenMPの観点からは、2つのコードが同等になります。これは、OpenMPコンパイラーが2つのケースでわずかに異なるコードを生成する可能性があるためです。

8
phadjido

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にリンクします

5
parcompute

明らかにたくさんの答えがありますが、これは非常にうまく答えています(ソース付き)

#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は新しいチームを作成し、そのチームを分割してループのさまざまな部分を処理します。プログラムに並列構造が含まれない場合、複数のスレッドが存在することはありません。非スレッドプログラムのように、プログラムを起動して実行するマスタースレッド。

https://bisqwit.iki.fi/story/howto/openmp/

4
fogx