c++ - 使用 omp 并行使用引用的函数

标签 c++ c++11 openmp

考虑简化的示例。假设我有以下功能:

int foo(int x, int y, bool &flag) {
  if (x == y)
    flag = true;
  return x + y;
}

然后使用 openmp 并行执行:

  bool flag = false;

#pragma omp parallel for 
  for (int i = 0; i < n; i++) {
    z[i] = foo(x[i], y[i], flag);
  }

我猜这里的问题是该函数被并行调用多次,并且每个实例都指向相同的标志。使用一些相对简单的解决方案来解决此问题的最佳方法是什么?

免责声明:我知道很多人会说以这种方式使用引用是不好的,但就我而言,这是实现任务的最简单方法:flag如果发生任何异常。

最佳答案

这会给你带来一场比赛。在这种特殊情况下,您可能不会遇到问题,因为线程只会在一个方向上更改变量,因此如果两个线程同时写入变量,则最终结果将是相同的。但这仍然很糟糕。

引用不是问题,当你不调用外部函数时也会有同样的问题。在下面的示例中,我不会使用外部函数,但这不会改变要点。

解决方案是使用 OpenMP 缩减:

int main() {
  int const n = 4;
  int x[n];
  int y[n];
  int z[n];

  bool flag = false;
#pragma omp parallel for reduction(|| : flag)
  for (int i = 0; i < n; i++) {
    if (x[i] == y[i])
      flag = true;
    z[i] = x[i] + y[i];
  }
}

每个线程现在都有自己的标志拷贝。在 parallel block (即 for 循环)的末尾,将使用“or”减少本地拷贝,并将其放入线程全局变量 标志

在其他情况下,您可以在该 if 语句周围放置一个 #pragma omp critical,但这会显着降低性能。

关于c++ - 使用 omp 并行使用引用的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47511835/

相关文章:

c++ - c 或 c++ 语言中的 rect

c++ - COM,包含 BSTR 的 VARIANT。谁分配?

c++ - Visual Studio 2008/10 的即时窗口中的 "search memory"是否损坏?

c++ - MFC,OPENFILENAME 结构 : m_ofn. lpstrCustomFilter

C 与 OpenMP : Matrix times vector

c++ - 编译器 : How is class instantiation code compiled?

c++ - 如何在没有等待结果的情况下触发内部循环异步任务

c++ - 当函数执行结束时, vector 中的线程会发生什么?

c++ - 使用openmp使用eigen c++的Jacobi算法的并行化

c++ - 使用 4 和 8 线程运行的相同时间执行