0

我正在编写一个物理模拟,该模拟主要由一个阵列上数千亿次重复操作的中央循环组成。这些操 这是我第一次做类似的事情,有人建议我看看 openmp。我已经开始用它编写一些玩具程序,但我真的不确定它是如何工作的,而且文档对我来说非常神秘。例如下面的代码:

int a = 0;
#pragma omp parallel
  {
    a++;
  }
   cout << a << endl;

在我的计算机上启动(4 核 CPU)有时给我 4,有时 3 或 2。是因为它不等待所有内核执行指令吗?因为我确实需要知道在我的案例中完成了多少次迭代。考虑到我到底想要什么,我应该寻找其他东西而不是 openmp 吗?

4

2 回答 2

0

当同时写入共享变量(a在您的代码中)时,您会遇到数据竞争。为避免不同线程“同时”写入,您必须使用原子分配或使用互斥锁(= 互斥)保护分配。在 OpenMP 中,后者是通过关键区域完成的

int a = 0;
#pragma omp parallel
{
#pragma omp critical
  {
    a++;
  }
}
cout << a << endl;

(当然,这个特定的程序不会并行执行,因此会比执行相同操作的串行程序慢)。

有关更多信息,请阅读 openMP 文档!但是,如果您使用 C++,我建议您不要使用 OpenMP,而是 TBB。它更加灵活。

于 2013-10-25T17:30:28.653 回答
0

您所看到的是竞争条件的典型示例。四个线程正在尝试增加变量a并且他们正在为它而战。有些“失败”并且它们无法增加,因此您会看到低于 4 的结果。

发生的情况是该a++命令实际上是一组三个指令:a从内存中读取并将其放入寄存器中,递增寄存器中的值,然后将值放回内存中。如果线程 1a在线程 2 读取它之后但在线程 2 将新值写回 之前读取了它的值,则线程 2a的递增操作将被覆盖。using#omp critical是一种确保所有读/增量/写操作不会被另一个线程中断的方法。

如果您需要并行化迭代,您可以使用omp parallel for, 例如递增数组中的所有元素。

典型用途:

#pragma omp parallel for
    for (i = 0; i < N; i++)
        a[i]++;
于 2013-10-25T19:10:12.757 回答