87

公式の定義を見てきましたが、まだかなり混乱しています。

firstprivate: 各スレッドが変数の独自のインスタンスを持つ必要があり、変数が変数の値で初期化される必要があることを指定します。これは、並列構造の前に存在するためです。

私には、それはプライベートのように聞こえます。例を探しましたが、それがどのように特別であるか、またはどのように使用できるかを理解していないようです。

lastprivate: 囲んでいるコンテキストの変数のバージョンが、最終反復 (for ループ コンストラクト) または最後のセクション (#pragma セクション) を実行するスレッドのプライベート バージョンに等しく設定されることを指定します。

次の例のおかげで、これを少しよく理解しているように感じます。

#pragma omp parallel
{
   #pragma omp for lastprivate(i)
      for (i=0; i<n-1; i++)
         a[i] = b[i] + b[i+1];
}
a[i]=b[i];

したがって、この例では、最後の値としてループの外側でlastprivatefor を返すことができることを理解しています。i

今日から OpenMP の学習を始めました。

4

3 に答える 3

179

private変数は初期化されません。つまり、他のローカル自動変数と同様にランダムな値で始まります (また、多くの場合、各スレッドのスタックで自動変数を使用して実装されます)。例として、次の簡単なプログラムを取り上げます。

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

int main (void)
{
    int i = 10;

    #pragma omp parallel private(i)
    {
        printf("thread %d: i = %d\n", omp_get_thread_num(), i);
        i = 1000 + omp_get_thread_num();
    }

    printf("i = %d\n", i);

    return 0;
}

4 つのスレッドを使用すると、次のような出力が得られます。

thread 0: i = 0
thread 3: i = 32717
thread 1: i = 32717
thread 2: i = 1
i = 10

(another run of the same program)

thread 2: i = 1
thread 1: i = 1
thread 0: i = 0
thread 3: i = 32657
i = 10

iこれは、 の値が並列領域内でランダム (初期化されていない) であり、それに対する変更が並列領域の後では見えないことを明確に示しています(つまり、変数は領域に入る前の値を保持しています)。

iが作成された場合firstprivate、並列領域の前の値で初期化されます。

thread 2: i = 10
thread 0: i = 10
thread 3: i = 10
thread 1: i = 10
i = 10

i並列領域内の値への変更は、その後は表示されません。

あなたはすでに知っていますlastprivate(そして、ワークシェアリング構造がないため、単純なデモ プログラムには適用できません)。

そうです、firstprivatelastprivateは の特殊なケースですprivate。1 つ目は外部コンテキストから並列領域に値を取り込み、2 つ目は並列領域から外部コンテキストに値を転送します。これらのデータ共有クラスの背後にある理論的根拠は、並列領域内ではすべてのプライベート変数が外部コンテキストの変数を隠しているためです。つまり、代入操作を使用して外部の値をi並列領域内から変更することはできません。

于 2013-03-09T10:13:22.197 に答える
8

firstprivatelastprivateは の特殊なケースですprivate

1 つ目は外部コンテキストから並列領域に値を取り込み、2 つ目は並列領域から外部コンテキストに値を転送します。

于 2017-01-20T10:10:27.233 に答える