我正在编写一个物理模拟程序,它主要包括一个中央循环,其中包含数千亿次数组上的重复操作。这些操作是相互独立的(实际上,数组在整个过程中会发生变化),因此我正在考虑将代码并行化,因为我可以让它在我实验室的4核或8核计算机上运行。这是我第一次做类似的事情,有人建议我去看看openmp。我已经开始用它编写一些玩具程序,但我真的不确定它是如何工作的,文档对我来说也相当神秘。例如下面的代码:
int a = 0;
#pragma omp parallel
{
a++;
}
cout << a << endl;在我的电脑(4核CPU)上运行时,有时会出现4次,有时会出现3次或2次。这是因为它不等待所有核心执行指令吗?因为我确实需要知道在我的例子中做了多少次迭代。考虑到我最终想要的是什么,我应该寻找比openmp更好的东西吗?
发布于 2013-10-26 01:30:29
当并发地写入一个共享变量(代码中的a)时,您会遇到数据竞争。为了避免不同的线程“同时”写入,必须使用原子赋值或使用互斥保护赋值(=互斥)。在OpenMP中,后者是通过临界区完成的
int a = 0;
#pragma omp parallel
{
#pragma omp critical
{
a++;
}
}
cout << a << endl;(当然,这个特定的程序不会并行执行任何操作,因此将比串行程序执行相同的操作要慢)。
有关更多信息,请阅读openMP文档!但是,我建议您不要使用OpenMP,但如果您使用C++,请使用TBB。它要灵活得多。
发布于 2013-10-26 03:10:13
您看到的是典型的race condition示例。有四个线程正在尝试递增变量a,它们正在为之而战。有些人“输了”,他们不能递增,所以你看到的结果小于4。
实际上,a++命令是一组三条指令:从内存中读取a并将其放入寄存器中,递增寄存器中的值,然后将值放回内存中。如果线程1在线程2读取a的值之后,但在线程2将新值写回a之前读取该值,则thread2的增量操作将被覆盖。使用#omp critical是一种确保所有读/增/写操作不会被另一个线程中断的方法。
如果需要并行化迭代,可以使用omp parallel for,例如递增数组中的所有元素。
典型用法:
#pragma omp parallel for
for (i = 0; i < N; i++)
a[i]++;https://stackoverflow.com/questions/19595912
复制相似问题