并行循环调用的函数中的 OpenMP 锁定指令

问题描述 投票:0回答:1

我有一个在并行 for 循环中调用的函数。除了需要锁定的一个变量增量之外,该函数中的所有内容都可以并行完成。我尝试将

#pragma omp atomic
放在指令之前,但似乎由于该函数仅在并行循环中调用,而不是自行并行化,因此编译器会调用错误:
error: ‘#pragma’ is not allowed here

我的代码看起来像这样(c++):

class MyClass {
private:
  int **data;
  int data_size;

public:
  size_t myFunc(int r, int i) {
    int n = longFunc(...); // Long code that can be done in parallel if needed
    for (int j = 0; j < data_size; j++) {
      #pragma omp atomic // error: ‘#pragma’ is not allowed here
      data[r][j] += n + data[i][i] + i;  // This part cannot be parallelised
    }

    return n;
  }
  /* ... */
};

int main() {
  MyClass s;

  int row_to_change = 0;
  #pragma omp parallel for
  for (int i = 0; i < s.size(); i++) {
    size_t n = s.myFunc(row_to_change, i); // Parallel calls to the function
    /* ... */
  }

  return 0;
}

知道如何保持

myFunc
的主要部分可能并行化,但在成员
data
的修改上锁定线程吗?

c++ parallel-processing locking openmp atomic
1个回答
0
投票

可能没有回答您真正的问题,而是纠正一个误解。 您声明“由于该函数仅在并行循环中调用,并且本身并未并行化,因此编译器会调用错误:错误:此处不允许‘#pragma’。”

然而,这是错误的。如果您在启用 OpenMP 的情况下进行编译,则可以在任何地方使用 OpenMP 原子操作,编译器不必看到代码完全处于任何并行性中。

考虑这样的代码:-

void lockedIncr(int *p)
{
  #pragma omp atomic
  (*p)++;
}

由于我们完全自行编译它,编译器显然无法知道它将被调用的上下文。

如果您在编译器资源管理器上查看here,您可以看到它已成功编译,并生成了人们期望的代码:-

lockedInc(int*):
        lock add        DWORD PTR [rdi], 1
        ret
© www.soinside.com 2019 - 2024. All rights reserved.