firstprivate 和 lastprivate 与 OpenMP 中的私有子句有何不同?

How are firstprivate and lastprivate different than private clauses in OpenMP?

提问人:SaiyanGirl 提问时间:3/9/2013 更新时间:12/7/2021 访问量:75516

问:

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

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

因此,在此示例中,我理解允许将 for 作为最后一个值返回到循环之外。lastprivatei

我今天刚开始学习 OpenMP。

OpenMP

评论

0赞 lylhw13 4/20/2022
请参阅第 106 页至第 111 页的文档Intro_To_OpenMP_Mattson.pdf。它有一个很好的解释。

答:

197赞 Hristo Iliev 3/9/2013 #1

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

如果 made ,则使用并行区域之前的值进行初始化:ifirstprivate

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

尽管如此,对并行区域内值的修改在它之后是不可见的。i

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

所以是的,只是 .第一个结果是将值从外部上下文引入并行区域,而第二个则将值从并行区域传输到外部上下文。这些数据共享类背后的基本原理是,在并行区域内,所有私有变量都隐藏了来自外部上下文的变量,即不可能使用赋值操作从并行区域内部修改外部值。firstprivatelastprivateprivatei

0赞 Muhammet Dabak 12/7/2021 #2

初始化前不能使用局部变量,程序会从 C++ 14 标准开始给出错误。i