Local Variables in a for loop openmp

Viewed 2499

I've just started to program with openmp and I'm trying to parallelize a for loop with a variable that I need out of the loop. Something like this:

float a = 0;
for (int i = 0; i < x; i++)
{
    int x = algorithm();
    /* Each loop, x have a different value*/
    a = a + x;
}
cout << a;

I think the variable a has to be a local variable for each thread. After those thread have ended their job, all the local variables a should be added into one final result.

How can I do that?

3 Answers

Use the #pragma omp parallel for reduction(+:a) clause before the for loop

variable declared within the for loop are local, as well as loop counters variable declared outside the #pragma omp parallel block are shared by default, unless otherwise specified (see shared, private, firstprivate clauses). Care should be taken when updating shared variables as a race condition may occur. In this case, the reduction(+:a) clause indicated that a is a shared variable on which an addition is performed at each loop. Threads will automatically keep track of the total amount to be added and safely increment a at the end of the loop.

Both codes below are equivalent:

float a = 0.0f;
int n=1000;
#pragma omp parallel shared(a) //spawn the threads
{
float acc=0;        // local accumulator to each thread
#pragma omp for     // iterations will be shared among the threads
for (int i = 0; i < n; i++){
      float x = algorithm(i); //do something
      acc += x;     //local accumulator increment
  } //for
#omp pragma atomic
a+=acc; //atomic global accumulator increment: done on thread at a time
} //end parallel region, back to a single thread
cout << a;

Is equivalent to:

float a = 0.0f;
int n=1000;
#pragma omp parallel for reduction(+:a)
for (int i = 0; i < n; i++){
    int x = algorithm(i);
    a += x;
    } //parallel for
cout << a;

Note that you can't make a for loop with a stop condition i<x where x is a local variable defined within the loop.

There are many mechanisms how to achieve your goal, but the most simple is to employ OpenMP parallel reduction:

float a = 0.0f;
#pragma omp parallel for reduction(+:a)
for(int i = 0; i < x; i++) 
  a += algorithm();
cout << a;

You can use the following structure to perform parallel reduction with thread-private containers since your update is scalar associative.

float a = 0;//Global and will be shared.
#pragma omp parallel 
{
    float y = 0;//Private to each thread
#pragma omp for
    for(int i = 0; i < x; i++)
         y += algorithm();//Better practice is to not use same variable as loop termination variable.
//Still inside parallel
#pragma omp atomic
    a += y;
 }
cout << a;
Related