私は公式の定義を見てきましたが、それでもかなり混乱しています。
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];
したがって、この例では、lastprivate
を使用すると、i
をループ外で最後の値として返すことができます。
今日からOpenMPの学習を始めました。
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
についてはすでに知っています(ワークシェアリング構造がないため、単純なデモプログラムには適用できません)。
はい、firstprivate
とlastprivate
はprivate
の特殊なケースです。 1つ目は値を外部コンテキストから並列領域に取り込み、2つ目は値を並列領域から外部コンテキストに転送します。これらのデータ共有クラスの背後にある理論的根拠は、並列領域内ではすべてのプライベート変数が外部コンテキストからの変数をシャドウすることです。つまり、代入操作を使用して内部からi
の外部値を変更することはできません並列領域。
firstprivate
とlastprivate
は、private
の特殊なケースです。
1つ目は値を外部コンテキストから並列領域に取り込み、2つ目は値を並列領域から外部コンテキストに転送します。