user995502
user995502

Reputation:

OpenMP parallel section dependency

I am running into a very odd OpenMP problem that I can't figure out. This is what it looks like.

I have (let's say)four functions

function0(Data *data) { ..body.. }
function1(Data *data) { ..body.. }
function2(Data *data) { ..body.. }
function3(Data *data) { ..body.. }

These function may or may not modify what is pointed by data

Here is how they are called sequentially

// Version 1

void test(Data *data)
{
    function0(data);
    function1(data);
    function2(data);
    function3(data);
}

I can rearrange the calls in anyway I want and it still works perfect. So i am assuming they are somehow(?) independent.

Now when parallelizing

// Version 2

void test(Data *data)
{
  int th_id;
#pragma omp parallel private(th_id) default(shared)
  {
    th_id = omp_get_thread_num();
    if(th_id==0) {
      function0(data);
    }

    if(th_id==1) {
      function1(data);
      }

    if(th_id==2){
      function2(data);
    }

    if(th_id==3){
      function3(data);
    }
  }
}

It DOESN'T work (version 2).

However if I synchronize the threads after each call it works

// Version 3

void test(Data *data)
{
  int th_id;
#pragma omp parallel private(th_id) default(shared)
  {
    th_id = omp_get_thread_num();
    if(th_id==0) {
      function0(data);
    }
#pragma omp barrier
    if(th_id==1) {
      function1(data);
      }
#pragma omp barrier
    if(th_id==2){
      function2(data);
    }
#pragma omp barrier
    if(th_id==3){
      function3(data);
    }
  }
}

I am thinking there is some data racing problem regarding what is pointed by data

But why would it work (in the sequential version 1) when I rearrange the calls then?

Upvotes: 0

Views: 269

Answers (1)

Jim Cownie
Jim Cownie

Reputation: 2859

Suppose you had two function like this

function0(int *data)
{
    *data = *data + 1;
}

function1(int *data)
{
    *data = *data + 2;
}

Clearly you can run those two operations in either order sequentially and at the end the value will have been incremented by 3. However, if you run the two functions in parallel you have a data race, and it's entirely posisble that one of the additions will be lost, so you could get any the initial value incremented by 1,2, or 3.

Just because the functions appear to be commutative sequentially that doesn't mean that they can safely be run in parallel.

Upvotes: 2

Related Questions