问题
I have this piece of code that is parallelized.
int i,n; double area,pi,x;
area=0.0;
#pragma omp parallel for private(x) reduction (+:area)
for(i=0; i<n; i++){
x= (i+0.5)/n;
area+= 4.0/(1.0+x*x);
}
pi = area/n;
It is said that the reduction will remove the race condition that could happen if we didn't use a reduction. Still I'm wondering do we need to add lastprivate for area since its used outside the parallel loop and will not be visible outside of it. Else does the reduction cover this as well?
回答1:
Reduction takes care of making a private copy of area
for each thread. Once the parallel region ends area is reduced in one atomic operation. In other words the area
that is exposed is an aggregate of all private area
s of each thread.
thread 1 - private area = compute(x)
thread 2 - private area = compute(y)
thread 3 - private area = compute(z)
reduction step - public area = area<thread1> + area<thread2> + area<thread3> ...
回答2:
You do not need lastprivate. To help you understand how reductions are done I think it's useful to see how this can be done with atomic
. The following code
float sum = 0.0f;
pragma omp parallel for reduction (+:sum)
for(int i=0; i<N; i++) {
sum += //
}
is equivalent to
float sum = 0.0f;
#pragma omp parallel
{
float sum_private = 0.0f;
#pragma omp for nowait
for(int i=0; i<N; i++) {
sum_private += //
}
#pragma omp atomic
sum += sum_private;
}
Although this alternative has more code it is helpful to show how to use more complicated operators. One limitation when suing reduction
is that atomic
only supports a few basic operators. If you want to use a more complicated operator (such as a SSE/AVX addition) then you can replace atomic
with critical
reduction with OpenMP with SSE/AVX
来源:https://stackoverflow.com/questions/16532229/what-is-the-usage-of-reduction-in-openmp