OpenMP中的firstprivate和lastprivate有何不同?


76

我已经看过官方定义,但我仍然很困惑。

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。

Answers:


151

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(由于缺少工作共享结构,因此它不适用于简单的演示程序)。

所以,是的,firstprivate而且lastprivate是只是特殊情况private。第一个结果将值从外部上下文引入并行区域,而第二个结果将值从并行区域传递到外部上下文。这些数据共享类背后的原理是,在并行区域内,所有私有变量都将外部变量遮盖起来,即,不可能使用赋值操作来修改i并行区域内的外部值。


1
这是一个很好的答案!非常感谢你!
SaiyanGirl 2013年

1
嗯,我说的评定者,firstprivatelastprivate是非常特殊的情况private。您通常甚至不需要使用private(只需在并行块内定义变量),就可以遮盖外部作用域。有趣的是,将C ++对象用作自动firstprivate变量-它们将通过复制构造初始化一次,然后在该块之后销毁,并且您无需事先知道线程数-创建的副本数与需要。
Tomasz Gandor 2014年

很好的例子!最喜欢。感谢赫里斯托。
Fusionmate'3

1
@TomaszGandor对于C ++,我不同意。随着private将默认每个线程,而不是每次迭代构建一次。如果它分配内存,则特别有用。
巴拉巴斯'16

firstprivate还可以有效地查询并行块中未更改的较小共享变量的值,例如参数标志。专用内存通常比共享内存快,并且如果只是布尔/逻辑标志,则冗余副本不会占用任何重要空间。
Astrokiwi

6

firstprivatelastprivate只是特殊情况private

第一个导致从外部上下文将值引入并行区域,而第二个导致将值从并行区域转移至外部上下文。


您能提供任何参考吗?
J. Chomel
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.