Search code examples
openmpreduction

Reduction in Openmp returns different results with the same number of threads in my code


My code with openmp using "reduction" doesn't return the same results from run to run.

Case 1: using "reduction"

sum = 0;
omp_set_num_threads(4);
#pragma omp parallel for reduction(+:sum)
for(ii = 0; ii < 100; i++)
   sum = sum + func(ii);

with func(ii) has side effects. In fact, func(ii) uses an other calcul() function which can lead to race condition in parallel execution. I think the calcul() function can be a reason for this problem. However, I use "critical", the results is always the same but this solution is not good for performance.

Case 2nd: using "critical"

sum = 0;
#pragma omp parallel for
for(ii = 0; ii < 100; i++)
{
   #pragma omp critical
   sum = sum + func(ii);
}

with the func(ii) function

func(int val) 
{
   read_file(val);
   calcul(); /*calculate something from reading_file(val)*/
   return val_fin;
}

Please help me to resolve it?

Thanks a lot!


Solution

  • Even if everything in the code is correct, you still might get different results from the OpenMP reduction due to the associativity of the operations (additions). To be able to reproduce the same result for a given number of threads, you need to implement the reduction yourself by storing the partial sum of each thread in a shared array. After the parallel region, the master thread can add these results. This approach implies that the threads always execute the same iterations, i.e. a static scheduling policy.

    Related question: Order of execution in Reduction Operation in OpenMP