首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenMP共享数据

OpenMP共享数据
EN

Stack Overflow用户
提问于 2011-05-10 06:40:42
回答 2查看 4.1K关注 0票数 3

我对OpenMP有点陌生,但一般都有并行处理方面的经验。我以前和boost::threads合作过,现在我正在用openmp进行测试。

问题是,我不知道如何处理共享数据访问,因为我不知道openmp在并行循环内部对共享数据对象做了什么。

我现在正在做的事情(到目前为止还在起作用):我用mmap将文件从磁盘读入内存。在内存映射部分之后,我收到char上的指针。

OpenMP现在可以在OpenMP并行循环中使用这个指针,并在线程之间共享数据。现在,我可以在映射和共享文件中搜索正则表达式匹配,多个线程根据(相当长的)正则表达式列表检查每个字符串。

我使这个列表(包含regex的向量)在openmp循环中是私有的,所以每个线程都有它自己的列表副本。

问题来了:

为了显着地提高我的应用程序的性能,我需要能够在匹配字符串后从这个向量中删除(regex-)项。

现在,所有其他活动线程都需要尽快将此项从它们的列表中删除。

因此,我将这个列表作为openmp循环中的共享数据对象,但现在当我尝试向列表写入(vector.erase(item#))时,在运行时得到分段错误。

有了boost::线程,我就会在写入/读取对象时使用互斥锁来锁定它。

但是openmp似乎处理了大多数同步本身,所以现在我想知道,在使用openmp时,使用openmp的正确方法是什么,这对我来说是新的。

EN

回答 2

Stack Overflow用户

发布于 2011-05-10 11:39:36

对于同步,可以使用#pragma omp critical或使用OpenMP锁例程(omp_{init,set,unset,destroy}_lock)。

当已知并行区域由单个线程执行时,#pragma omp critical的优点是简单和能够忽略该实用程序。缺点是只适用于单个并行区域,以及该区域内的全局影响:没有其他线程能够执行该区域中的任何其他关键部分。

OpenMP锁例程类似于大多数其他可用的锁,例如那些线程或Boost的锁(撇开RAII不说)。初始化一个锁对象,然后使用它来保护某些关键部分,并在没有必要时销毁它。这些锁可以用来保护对来自不同并行区域的数据的访问,构建分布式锁定方案等;但是,总是会产生一定的开销,而且与#pragma omp critical相比,使用起来肯定更“毛茸茸”。

然而,我要对并行解决方案的设计提出质疑。从向量中间擦除元素会使所有迭代器失效,并移动元素。擦除被认为是一种罕见的操作(否则,即使在串行代码中,矢量的选择也是有问题的),但由于上述效果,您也必须保护所有的向量读取,这可能会花费很大的代价。读/写锁可以缓解一些问题,但这些锁在OpenMP中是不可用的,因此您需要使用特定于平台的接口或第三方库。

我认为以下几点可能会更好:

  • 将regex向量保持为私有,并添加相同大小的共享标志向量,这些标志指示某个正则表达式是否仍然有效。
  • 在应用来自私有向量的某个正则表达式之前,如果该正则表达式未被其他线程“擦除”,代码将在共享向量中进行检查。如果是,将跳过正则表达式。
  • 在找到匹配后,代码将与当前正则表达式对应的共享向量的元素标记为“擦除”,以便从现在起忽略它。

在此方案中,存在读取/写入标志的竞赛:可能会将标志设置为“擦除”,直到下一分钟它被另一个线程读取为“有效”。结果,两个不同的线程可能同时为相同的正则表达式找到匹配。但是,我认为,在当前解决方案中,所有regex容器都是私有的,以及具有共享容器和锁或RW锁的解决方案中存在这个问题,除非非RW锁也用给定的正则表达式保护操作。如果多个比赛是一个问题,这一切都应该重新考虑。

票数 3
EN

Stack Overflow用户

发布于 2011-05-10 06:54:15

您可以通过创建一个关键部分来实现这一点。

代码语言:javascript
复制
#pragma omp critical
{
   ...some synchronized code...
}

编辑:删除了关于‘#语用omp原子’的部分,因为它无法原子地执行所需的操作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5946167

复制
相关文章

相似问题

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