并行循环上的死锁

时间:2016-01-23 17:20:06

标签: c++ parallel-processing locking openmp

我试图并行化下面的代码。很容易看出aux的值之间存在依赖关系,因为它们是在内部循环之后计算的,但是在内部循环中需要它们(注意在第一次迭代时j = 0) ,内循环内的代码不执行)。另一方面,mu值之间没有依赖关系,因为我们只更新mu[k],但其他计算所需的唯一值在mu[j]0 <= j < k

我的方法是将aux的元素锁定,直到计算出来。一旦计算出aux的给定值,就会释放该元素的锁定,并且每个线程都可以使用它。但是,使用此代码会发生死锁,我无法弄清楚原因。有人有任何提示吗?

由于

for (j = 0; j < k; ++j)
    locks[j] = 0;

#pragma omp parallel for num_threads(N_THREADS) private(j, i)
for (j = 0; j < k; ++j)
{
  vals[j] = (long)0;

  for (i = 0; i < j; i++)
  {
    while(!locks[i]);
    vals[j] += mu[j][i] * aux[i];
  }

  aux[j] = (s[j] - vals[j]);
  locks[j] = 1;

  mu[k][j] = aux[j] / c[j];
}

1 个答案:

答案 0 :(得分:0)

未优化时是否也会挂起? 在优化代码中,gcc不会多次阅读locks[i],因此:

for (i = 0; i < j; i++) {
  while(!locks[i]);

就像写作:

for (i = 0; i < j; i++) {
  if( !locks[i] ) for(;;) {}

尝试添加一个屏障来强制gcc重新读取锁[i]:

#define pause() do { asm volatile("pause;":::"memory"); } while(0)
...

  for (i = 0; i < j; i++) {
    while(!locks[i]) pause();

HTH