这是我的代码的大纲:
#pragma omp parallel default(shared)
{
for(i; i<lim; i++)
do_work();
}
过了一会儿:
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++;
}
编译时出现以下错误:
减少变量“结果”在外部上下文中是私有的
这不应该发生,因为根据IBM 编译器文档,该reduction
子句
使用指定的运算符对列表中的所有标量变量执行归约。列表中的归约变量用逗号分隔。
为每个线程创建列表中每个变量的私有副本。在语句块的末尾,归约变量的所有私有副本的最终值以适合运算符的方式组合,并将结果放回共享归约变量的原始值中。
减少子句中指定的变量:
- 必须是适合操作员的类型。
- 必须在封闭的上下文中共享。
- 不能是 const 限定的。
- 不能有指针类型。
重点补充。由于外部并行区域应该将所有变量处理为shared
,这意味着一旦发现它的减少就result
应该转换为。private
至少不应该private
在外部范围内考虑它,因为外部范围已明确告诉每个变量都是shared
. 这就是我困惑的根源。
当然,我使用的是 GCC 而不是 IBM 编译器,但在这种情况下有区别吗?
所以我想我的问题是:为什么 OpenMP 对待归约 var。当它先前在外部上下文中声明为共享时作为私有变量?
我只有减少这个问题,其他一切都按预期工作(特别是当有一个例子可以做完全相同的事情时)。