I am trying to understand how OMP treats different for
loop declarations. I have:
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;
}
where {...}
are the numbers form 1 to 10000. This code prints the correct value. If instead of #pragma omp parallel for reduction(+:ave)
I use #pragma omp parallel for private(ave)
the result of the printf
is 0.0000
. I think I understand what reduction(oper:list)
does, but was wondering if it can be substituted for private
and how.
So yes, you can do reductions without the reduction
clause. But that has a few downsides that you have to understand:
critical
construct.Anyway, here is an example of that using your code:
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;
}
This is a classical method for doing reductions by hand, but notice that the variable that would have been declared reduction
isn't declared private
here. What becomes private
is a local substitute of this variable while the global one must remain shared
.