【问题标题】:OpenMP Deadlock utilizing omp_set_lock利用 omp_set_lock 的 OpenMP 死锁
【发布时间】:2020-04-08 10:06:28
【问题描述】:

我有一个具有以下一般结构的函数:

void a_generic_function(int N, int *arr, int *superarr)
{
  //some code
  for (int i = 0; i < N; i++)
  {
    omp_init_lock(&(lock[i])); //Initializes N locks, lock is allocated dynamic mem previously.
  }
  #pragma omp parallel shared(lock)
  {
    #pragma omp for
    {
      for (int i = 1; i <= N; i++)
      {
        //some code
        for (int j = arr[i-1]; j < arr[i]; i++) //where arr is size N+1
        {
          //some code
          for (int k = 0; k < temp; k++) //where temp < N
          {
            omp_set_lock(&(lock[subarr[k]])); //subarr is size <= N
            superarr[subarr[k]] += temp-1; //superarr is size = N. Temp is an int value.
            omp_unset_lock(&(lock[subarr[k]]));
          }
        }
      }
    }
  }
}

这段代码中只有一个点限制线程进入,一旦关键操作完成就应该立即解锁,但是这个函数经常会死锁。 我不明白是什么原因造成的。

(为了完整起见:在这个函数之外没有并行化)

【问题讨论】:

  • 不回答您的问题,但请阅读 OpenMP 原子操作(这将使您消除这里的所有锁定!)

标签: c locking openmp deadlock


【解决方案1】:

太多的“// 一些代码”可以肯定,但对我来说问题是你没有释放你设置的相同的锁,即subarr[k] 的值在你调用omp_set_lock 之后和@之前发生变化987654323@。一种可能的解决方案是创建一个线程私有变量,例如

int n = subarr[k];
omp_set_lock(&lock[n]);
// do stuff
omp_unset_lock(&(lock[n]));

这确保线程释放它设置的相同锁。

作为奖励:您可以安全地将#pragma omp parallel for 放在您的锁定初始化循环中以提高性能。

【讨论】:

    猜你喜欢
    • 2015-01-25
    • 2017-01-24
    • 2021-11-18
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 2013-06-05
    • 2019-04-23
    • 1970-01-01
    相关资源
    最近更新 更多