2013-03-08 48 views
48

我看了官方定义,但我仍然很困惑。在OpenMP中,firstprivate和lastprivate与private子句有何不同?

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今天。

回答

103

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

四个线程它输出类似:

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(并且它不适用于简单演示程序,因为它缺少工作共享结构)。因此,和lastprivate只是private的特例。第一个结果是将来自外部上下文的值引入并行区域,而第二个将来自并行区域的值传送到外部上下文。这些数据共享类背后的基本原理是在并行区域内,所有私有变量都会影响外部环境中的私有变量,即无法使用赋值操作来修改并行区域内的外部值i

+1

这是一个很好的答案!非常感谢你! – SaiyanGirl 2013-03-11 16:29:43

+0

好吧,我会说rater,'firstprivate'和'lastprivate'是'private'的非常特殊情况。您通常甚至不需要使用'private'(只需在并行块中定义变量),可能会影响外部范围。有趣的是将C++对象用作自动'firstprivate'变量 - 它们将通过copy-construction初始化一次,并在块之后被销毁,并且不需要事先知道线程数量 - 根据需要创建。 – 2014-09-18 07:26:17

+0

这样一个很好的例子!最喜欢它。感谢Hristo。 – Fusionmate 2015-03-02 07:55:57

1

firstprivatelastprivate只是private的特殊情况。

第一个将外部上下文中的值引入并行区域,第二个将值从并行区域传递到外部上下文。

+0

可否提供任何有关它的参考? – 2017-01-20 10:41:43

相关问题