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。
private
variables不会被初始化,也就是说,像任何其他本地自动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在进入区域之前保持它的值)之后对它的任何修改是不可见的。
如果i
是firstprivate
,那么它是用平行区域之前的值初始化的:
thread 2: i = 10 thread 0: i = 10 thread 3: i = 10 thread 1: i = 10 i = 10
平行区域内的i
的值的修改在它之后是不可见的。
你已经知道lastprivate
(它不适用于简单的演示程序,因为它缺less工作分享结构)。
所以是的, firstprivate
和lastprivate
只是private
特殊情况。 第一个结果是将来自外部环境的值引入并行区域,而第二个将值从并行区域转移到外部环境。 这些数据共享类背后的基本原理是在并行区域内部,所有私有variables都会影响外部环境下的私有variables,也就是说不可能使用赋值操作来从并行区域内部修改i
的外部值。
firstprivate
和lastprivate
只是private
特殊情况。
第一个结果是将来自外部环境的值引入并行区域,而第二个将值从并行区域转移到外部环境。