firstprivate和lastprivate在OpenMP中如何与private子句不同?

我看了官方的定义,但是我还是很困惑。

firstprivate :指定每个线程应该有自己的variables实例,并且该variables应该用variables的值初始化,因为它存在于并行构造之前。

对我来说,这听起来很像私人。 我已经查找了一些例子,但我似乎并不了解它是如何特殊的,或者它如何被使用。

lastprivate :指定将封闭上下文的variables版本设置为执行最终迭代(for-loop结构)或最后一个部分(#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。

privatevariables不会被初始化,也就是说,像任何其他本地自动variables一样,它们以随机值开始(并且它们通常使用每个线程的堆栈上的自动variables来实现)。 以这个简单的程序为例:

 #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; } 

有四个线程输出类似于:

 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的值在并行区域内是随机的(没有初始化),并且在并行区域(即variables在进入区域之前保持它的值)之后对它的任何修改是不可见的。

如果ifirstprivate ,那么它是用平行区域之前的值初始化的:

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

平行区域内的i的值的修改在它之后是不可见的。

你已经知道lastprivate (它不适用于简单的演示程序,因为它缺less工作分享结构)。

所以是的, firstprivatelastprivate只是private特殊情况。 第一个结果是将来自外部环境的值引入并行区域,而第二个将值从并行区域转移到外部环境。 这些数据共享类背后的基本原理是在并行区域内部,所有私有variables都会影响外部环境下的私有variables,也就是说不可能使用赋值操作来从并行区域内部修改i的外部值。

firstprivatelastprivate只是private特殊情况。

第一个结果是将来自外部环境的值引入并行区域,而第二个将值从并行区域转移到外部环境。