【问题标题】:How are firstprivate and lastprivate different than private clauses in OpenMP?在 OpenMP 中,firstprivate 和 lastprivate 与 private 子句有何不同?
【发布时间】:2013-02-24 15:11:24
【问题描述】:

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

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

对我来说,这听起来很像私人的。我找了一些例子,但我似乎不明白它有什么特别之处或如何使用它。

lastprivate:指定封闭上下文的变量版本设置为等于执行最终迭代(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。

【问题讨论】:

    标签: openmp


    【解决方案1】:

    在初始化之前不能使用局部变量i,程序会报错,因为C++ 14 Standard。

    【讨论】:

      【解决方案2】:

      firstprivatelastprivate 只是private 的特例。

      第一个导致将来自外部上下文的值带入并行区域,而第二个导致将值从并行区域传输到外部上下文。

      【讨论】:

      • 你能提供任何关于它的参考吗?
      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-13
        • 1970-01-01
        • 1970-01-01
        • 2017-10-13
        相关资源
        最近更新 更多