OpenMP并行段依赖

时间:2013-03-06 16:32:29

标签: parallel-processing synchronization openmp

我遇到了一个非常奇怪的OpenMP问题,我无法弄明白。这就是它的样子。

我(让我们说)有四个功能

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

这些功能可能会也可能不会修改data

指向的内容

以下是按顺序调用它们的方式

// Version 1

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

我可以随心所欲地重新安排电话,但它仍然可以完美无缺。所以我假设他们不知何故(?)独立。

现在并行化时

// 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);
    }
  }
}

它不起作用(版本2)。

但是如果我在每次调用后同步线程就可以了

// 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);
    }
  }
}

我在想data

指出的问题存在一些数据竞争问题

但是当我重新安排呼叫时,为什么它会工作(在顺序版本1中)?

1 个答案:

答案 0 :(得分:2)

假设您有两个这样的功能

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

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

显然,您可以按顺序以任意顺序运行这两个操作,最后该值将增加3。 但是,如果你并行运行这两个函数,那么你就会有一个数据竞争,并且它的一个添加内容将会丢失,所以你可以得到任何初始值增加1,2或3。

仅仅因为这些函数似乎是可交换的顺序,并不意味着它们可以安全地并行运行。