gpt4 book ai didi

c++ - OpenMP 共享数据

转载 作者:太空狗 更新时间:2023-10-29 21:07:04 25 4
gpt4 key购买 nike

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

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

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

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

我在 openmp 循环中将此列表(包含正则表达式的 vector )设为私有(private),因此每个线程都有自己的此列表拷贝。

问题来了:

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

现在所有其他事件线程也需要尽快将此项目从他们的列表中删除。

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

使用 boost::threads 我会在写入/读取对象时使用互斥锁来锁定它。

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

最佳答案

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

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

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

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

我认为以下可能会更好:

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

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

关于c++ - OpenMP 共享数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5946167/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com