首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >共享一个对象但又相互独立的任务并行的最好方法是什么?

共享一个对象但又相互独立的任务并行的最好方法是什么?
EN

Stack Overflow用户
提问于 2013-10-26 01:21:37
回答 2查看 102关注 0票数 0

我正在编写一个物理模拟程序,它主要包括一个中央循环,其中包含数千亿次数组上的重复操作。这些操作是相互独立的(实际上,数组在整个过程中会发生变化),因此我正在考虑将代码并行化,因为我可以让它在我实验室的4核或8核计算机上运行。这是我第一次做类似的事情,有人建议我去看看openmp。我已经开始用它编写一些玩具程序,但我真的不确定它是如何工作的,文档对我来说也相当神秘。例如下面的代码:

代码语言:javascript
复制
int a = 0;
#pragma omp parallel
  {
    a++;
  }
   cout << a << endl;

在我的电脑(4核CPU)上运行时,有时会出现4次,有时会出现3次或2次。这是因为它不等待所有核心执行指令吗?因为我确实需要知道在我的例子中做了多少次迭代。考虑到我最终想要的是什么,我应该寻找比openmp更好的东西吗?

EN

回答 2

Stack Overflow用户

发布于 2013-10-26 01:30:29

当并发地写入一个共享变量(代码中的a)时,您会遇到数据竞争。为了避免不同的线程“同时”写入,必须使用原子赋值或使用互斥保护赋值(=互斥)。在OpenMP中,后者是通过临界区完成的

代码语言:javascript
复制
int a = 0;
#pragma omp parallel
{
#pragma omp critical
  {
    a++;
  }
}
cout << a << endl;

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

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

票数 0
EN

Stack Overflow用户

发布于 2013-10-26 03:10:13

您看到的是典型的race condition示例。有四个线程正在尝试递增变量a,它们正在为之而战。有些人“输了”,他们不能递增,所以你看到的结果小于4。

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

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

典型用法:

代码语言:javascript
复制
#pragma omp parallel for
    for (i = 0; i < N; i++)
        a[i]++;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19595912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档