当前位置: 动力学知识库 > 问答 > 编程问答 >

c - Why can't I use reduction with default(shared)?

问题描述:

Here's the outline of my code:

#pragma omp parallel default(shared)

{

for(i; i<lim; i++)

do_work();

}

And a while later:

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

}

When compiled I get the following error:

reduction variable ‘result’ is private in outer context

which shouldn't be happening because according to the IBM compiler documentation the reduction clause

Performs a reduction on all scalar variables in list using the specified operator. Reduction variables in list are separated by commas.

A private copy of each variable in list is created for each thread. At the end of the statement block, the final values of all private copies of the reduction variable are combined in a manner appropriate to the operator, and the result is placed back into the original value of the shared reduction variable.

Variables specified in the reduction clause:

  • must be of a type appropriate to the operator.
  • must be shared in the enclosing context.
  • must not be const-qualified.
  • must not have pointer type.

Emphasis added. Since the outer parallel region is supposed to handle all variables as shared, which means that result should get converted to private once a reduction on it is found. At the very least though it shouldn't be considered private in the outer scope, because the outer scope has explicitly told every variable to be shared. That's the source of my confusion.

Granted I'm using GCC instead of the IBM compiler but is there a difference in this case?

So I guess my question is: Why does OpenMP treat a reduction var. as a private variable when it's previously declared as shared in the outer context?

I only have this problem with reductions, everything else works as it's supposed to (especially when there's an example which does the exact same thing).

网友答案:

bar() is being called by each OpenMP thread independently and there is one result variable in the stack of each thread, therefore there are as many result variables as is the number of threads. No thread knows where the others store their results and it is not possible (and makes no sense) to reduce them together. That is why automatic variables in functions called from inside a parallel region are predetermined to be private and this cannot be changed since threads do not share stack space. The same applies for variables declared inside the parallel region - they do not exist before the region and exist only on the stacks of each executing thread. reduction only works on shared variables that exist in the other scope, i.e. are either declared before the parallel region, or are static, or are global.

网友答案:

Anythig defined in the parallel block should be private.

The difference between yours and the link you provided is result is already defined outside the parallel block in your link, so it can be declared as shared.

分享给朋友:
您可能感兴趣的文章:
随机阅读: