OpenMP:循环结转依赖

OpenMP: Loop Carry over dependency

本文关键字:依赖 循环 OpenMP      更新时间:2023-10-16

我想在c++中实现一个简单的累积和代码,如下所示:

x[0] = 0;
for (k=1;k<100; k++)
   x[k] = x[k-1] + x[k];

在这个站点上,一个实现被记录下来以消除循环结转依赖。对于两个线程,代码应该如下所示:

x[0] = 0;
x[49] = 74; //pre calculated
//the outer loop is parallelized (two instances)
#pragma omp parallel for private(m,k)
  for(m=0;m<2;m++) {
    for (k=m*49+1; k<m*50+50; k++) {
       x[k] = x[k-1] + x[k];
    }
  }

问题是我仍然在这里看到循环携带依赖(两个线程并行运行,但一个需要来自另一个的数据)。

谁能在这里加些解释吗?消除这种依赖的最好方法是什么?

由于x[49]的值已经存在,所以不需要再计算它:您可以跳过k = 0k = 49的迭代。这就是为什么循环在两个嵌套循环中展开。

然而,这里似乎有一个错误。对于内部循环应该只有一个循环携带依赖,并且它应该跨外部循环的迭代传播。这是因为没有正确定义限制:

  • m = 0, k = 1 .. 48(你已经得到0和49)。
  • m = 1, k = 50 ..99(再次,你已经得到了49!)。

因此,循环应该如下所示:

for( m = 0; m < 2; m++ ) {
  for (k=m*49+1; k<m*51+49; k++) {
    x[k] = x[k-1] + x[k];
  }
}

如果您将添加更改为:

x[k+1] = x[k] + x[k+1];

它可以简化一点你的下界…

for( m = 0; m < 2; m++ ) {
  for (k=m*50; k < m*51+48; k++) {
    x[k+1] = x[k] + x[k+1];
  }
}