private variables vs reduction in OMP

Peter Hristov Source

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.

copenmppragma

answered 6 months ago Gilles #1

So yes, you can do reductions without the `reduction` clause. But that has a few downsides that you have to understand:

1. You have to do things by hand, which is more error-prone:
• declare local variables to store local accumulations;
• initialize them correctly;
• accumulate into them;
• do the final reduction in the initial variable using a `critical` construct.
2. This is harder to understand and maintain
3. This is potentially less effective...

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`.