Tim
Tim

Reputation: 7464

Function using reference in parallel using omp

Consider the simplified example. Say that I have the following function:

int foo(int x, int y, bool &flag) {
  if (x == y)
    flag = true;
  return x + y;
}

that then is executed in parallel using openmp:

  bool flag = false;

#pragma omp parallel for 
  for (int i = 0; i < n; i++) {
    z[i] = foo(x[i], y[i], flag);
  }

I guess that the problem in here is that the function gets called multiple times in parallel and each of the instances points to the same flag. What is the best way to fix this using some comparably simple solution?

Disclaimer: I know that many people would say that using reference in such way is bad, but in my case it is the simplest way to achieve the task: flag if any exception happens.

Upvotes: 2

Views: 634

Answers (1)

Martin Ueding
Martin Ueding

Reputation: 8709

This will give you a race. In this particular case you might not have a problem because the threads will only change the variable in one direction, so if two threads write on it at the same moment, the end result will be same either way. But still this is bad.

The reference is not a problem, you have the same issue when you do not call an external function. In my following example I will not use an external function but that does not change the gist.

The solution is to use an OpenMP reduction:

int main() {
  int const n = 4;
  int x[n];
  int y[n];
  int z[n];

  bool flag = false;
#pragma omp parallel for reduction(|| : flag)
  for (int i = 0; i < n; i++) {
    if (x[i] == y[i])
      flag = true;
    z[i] = x[i] + y[i];
  }
}

Each thread will now have its own copy of flag. At the end of the parallel block, which is the for loop, the local copies will be reduced using “or” and that is put into the thread-global variable flag.

In other cases you can put an #pragma omp critical around that if statement, but that would reduce your performance significantly.

Upvotes: 5

Related Questions