【问题标题】:OpenMP shared dataOpenMP 共享数据
【发布时间】:2011-08-22 05:11:00
【问题描述】:

我对 OpenMP 有点陌生,但总体上具有并行处理方面的经验。我之前使用过 boost::threads,现在我正在使用 openmp 进行测试。

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

我现在正在做的事情(到目前为止一直有效):我使用 mmap 将文件从磁盘读取到内存中。我在内存映射部分之后收到一个关于 char 的指针。

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

我在 openmp 循环中将这个列表(一个包含正则表达式的向量)设为私有,所以每个线程都有它自己的这个列表的副本。

问题来了:

为了显着提高我的应用程序的性能,我需要能够在匹配字符串后从该向量中删除(正则表达式)项目。

现在所有其他活动线程也需要尽快从他们的列表中删除该项目。

所以我将此列表设为 openmp 循环内的共享数据对象,但现在当我尝试将 (vector.erase(item#)) 写入列表时,我在运行时遇到分段错误。

有了 boost::threads,我就可以在写/读时使用互斥锁来锁定这个对象。

但是 openmp 似乎自己处理了大部分同步,所以现在我想知道在使用对我来说是新的 openmp 时处理这个问题的正确方法是什么。

【问题讨论】:

  • 你有一个最小的例子来说明这个问题吗?

标签: c++ openmp shared


【解决方案1】:

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

#pragma omp critical 的好处是简单,并且能够在已知并行区域由单个线程执行时忽略编译指示。缺点是仅适用于单个并行区域,并且在该区域内具有全局效果:没有其他线程可以执行该区域中的任何其他临界区。

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

但是,我会挑战并行解决方案的设计。从向量中间擦除一个元素会使所有迭代器失效,并移动元素。擦除应该是一种罕见的操作(否则,即使在我认为的串行代码中,向量的选择也是有问题的),但由于上述影响,您也必须保护向量的所有读取,这可能会很昂贵。读/写锁可以缓解一些问题,但这些在 OpenMP 中不可用,因此您需要使用特定于平台的接口或第 3 方库。

我认为以下可能会更好:

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

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

【讨论】:

    【解决方案2】:

    您可以通过创建临界区来实现这一点。

    #pragma omp critical
    {
       ...some synchronized code...
    }
    

    编辑: 删除了关于“#pragma omp atomic”的部分,因为它不能原子地执行所需的操作。

    【讨论】:

    • #pragma omp atomic 在那里允许的表达式非常有限。您提供的示例不符合 OpenMP 规范。我建议您从答案中删除相应的部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-14
    • 1970-01-01
    • 2021-08-13
    • 2012-06-14
    • 2012-07-05
    相关资源
    最近更新 更多