私有变量与OMP的减少

时间:2018-03-14 12:48:17

标签: c openmp pragma

我试图了解OMP如何处理不同的for循环声明。我有:

int main()
{
   int i, A[10000]={...};
   double ave = 0.0;
   #pragma omp parallel for reduction(+:ave)
   for(i=0;i<10000;i++){
       ave += A[i];
   }

   ave /= 10000;

   printf("Average value = %0.4f\n",ave);
   return 0;
}

其中{...}是从1到10000的数字。此代码打印正确的值。如果我使用#pragma omp parallel for reduction(+:ave)代替#pragma omp parallel for private(ave),则printf的结果为0.0000。我想我理解reduction(oper:list)的作用,但想知道它是否可以替代private以及如何。

1 个答案:

答案 0 :(得分:3)

所以是的,您可以在没有reduction子句的情况下进行缩减。但这有一些你必须要理解的缺点:

  1. 你必须手工做事,这更容易出错:
    • 声明局部变量以存储本地累积;
    • 正确初始化它们;
    • 累积进去;
    • 使用critical构造完成初始变量的最终缩减。
  2. 这很难理解和维护
  3. 这可能效果不佳......
  4. 无论如何,这是一个使用你的代码的例子:

    int main() {
       int i, A[10000]={...};
       double ave = 0.0;
       double localAve;
    
       #pragma omp parallel private( i, localAve )
       {
           localAve = 0;
           #pragma omp for
           for( i = 0; i < 10000; i++ ) {
               localAve += A[i];
           }
           #pragma omp critical
           ave += localAve;
       }
    
       ave /= 10000;
    
       printf("Average value = %0.4f\n",ave);
       return 0;
    }
    

    这是手工减少的经典方法,但请注意,此处声明reduction的变量未声明为private。成为private的内容是此变量的本地替代,而全局变量必须保留shared