为什么我不能使用默认值(共享)?

rat*_*ath 0 c parallel-processing openmp

这是我的代码的大纲:

#pragma omp parallel default(shared)
{
for(i; i<lim; i++)
    do_work();
}
Run Code Online (Sandbox Code Playgroud)

过了一会儿:

do_work(){
    foo();
    bar();
}

foo(){
    #pragma omp for //etc
    for(i;i<l;i++) //your typical loop
}

bar(){ //here's the interesting part
    int i;
    int result;

    #pragma omp for reduction(+:result) private(i)
    for(i=0; i<lim; i++)
        result++;
}
Run Code Online (Sandbox Code Playgroud)

编译时我收到以下错误:

减少变量'result'在外部上下文中是私有的

这不应该发生,因为根据IBM编译器文档reduction条款

使用指定的运算符对列表中的所有标量变量执行减少.列表中的减少变量用逗号分隔.

为每个线程创建列表中每个变量的私有副本.在语句块的末尾,缩减变量的所有私有副本的最终值以适合于操作符的方式组合,并且结果被放回到共享缩减变量的原始值中.

减少条款中指定的变量:

  • 必须是适合操作员的类型.
  • 必须在封闭的上下文中共享.
  • 不能是const限定的.
  • 不能有指针类型.

强调补充说.由于外部并行区域应该处理所有变量shared,这意味着一旦发现它的减少就result应该转换为private.至少虽然它不应该private在外部范围内考虑,因为外部范围已明确告知每个变量shared.这是我困惑的根源.

当然我使用的是GCC而不是IBM编译器,但这种情况有区别吗?

所以我想我的问题是:为什么OpenMP会处理减少变量.作为私有变量,它之前被声明为在外部上下文中共享?

我只有减少这个问题,其他一切都按预期工作(特别是当有一个例子完全相同的事情).

Hri*_*iev 5

bar()每个OpenMP线程独立调用,每个线程result的堆栈中都有一个变量,因此result线程数量和变量一样多.没有线程知道其他人存储他们result的位置,并且不可能(并且没有意义)将它们一起减少.这就是为什么从并行区域内部调用的函数中的自动变量被预先确定的原因,private并且由于线程不共享堆栈空间,因此无法更改.这同样适用于在并行区域内声明的变量 - 它们在区域之前不存在,并且仅存在于每个执行线程的堆栈中.reduction仅适用于另一个范围内存在的共享变量,即在并行区域之前声明,或者是static,或者是全球的.