OpenMP 共享数据
OpenMP shared data
我对OpenMP有点陌生,但总体上具有并行处理的经验。我以前和boost::threads
一起工作过,现在我正在使用openmp进行测试。
问题是我不知道如何处理共享数据访问,因为我真的不知道 openmp 在内部对并行循环中的共享数据对象做了什么。
我现在正在做什么(到目前为止这是有效的):我使用 mmap 将文件从磁盘读取到内存中。我在内存映射部分之后收到一个关于字符的指针。
OpenMP现在可以在 OpenMP 并行 for 循环中使用此指针,并在线程之间共享数据。我现在能够在映射和共享文件中搜索正则表达式匹配项,多个线程根据(相当长的)正则表达式列表检查每个字符串。
我在 openmp 循环中将此列表(包含正则表达式的向量)设为私有,因此每个线程都有自己的此列表副本。
问题来了:
为了显着提高应用程序的性能,我需要能够在匹配字符串后从此向量中删除 (regex-) 项。
现在,所有其他活动线程也需要尽快从其列表中删除此项。
所以我使这个列表成为openmp循环中的共享数据对象,但现在当我尝试将(vector.erase(item#))写入列表时,我在运行时出现分段错误。
使用boost::threads,我只会使用互斥锁在写入/读取此对象时锁定此对象。
但是 openmp 似乎可以处理大部分同步本身,所以现在我想知道在使用对我来说很新的 openmp 时处理这个问题的正确方法是什么。
对于同步,您可以使用#pragma omp critical
也可以使用 OpenMP 锁定例程 ( omp_{init,set,unset,destroy}_lock
)。
#pragma omp critical
的好处是简单,并且当已知并行区域由单个线程执行时,能够忽略杂注。缺点是仅适用于单个并行区域,以及该区域内的全局效应:没有其他线程可以执行该区域中的任何其他关键部分。
OpenMP 锁例程类似于大多数其他可用的锁,例如 pthreads 或 Boost(RAII 除外)的锁。您初始化一个锁定对象,然后使用它来保护某些关键部分,并在不必要的情况下销毁。这些锁可用于保护对来自不同并行区域的数据的访问,构建分布式锁定方案等;但是总是会产生一定的开销,并且与#pragma omp critical
相比,使用肯定更"毛茸茸"。
但是,我会挑战并行解决方案的设计。从向量中间擦除元素会使所有迭代器失效,并移动元素。擦除被认为是一种罕见的操作(否则,我认为即使在串行代码中,矢量的选择也是有问题的),但由于上述影响,您还必须保护矢量的所有读取,这可能会很昂贵。读/写锁可以减轻一些负担,但这些锁在 OpenMP 中不可用,因此您需要使用特定于平台的接口或第三方库。
我认为以下内容可能会更好:
- 您将正则表达式向量
- 保密,并添加相同大小的共享标志向量,以指示某个正则表达式是否仍然有效。
- 在从私有向量应用某个正则表达式之前,代码会在共享向量中检查此正则表达式是否未被其他线程"擦除"。如果是,则跳过正则表达式。
- 找到匹配项后,代码将与当前正则表达式对应的共享向量的元素标记为"擦除",以便从现在开始将其忽略。
在这个方案中,存在读取/写入标志的竞赛:一个标志可能会在被另一个线程读取为"有效"的下一刻被设置为"擦除"。因此,两个不同的线程可能会同时找到同一正则表达式的匹配项。但是,我相信这个问题存在于您当前的解决方案中,其中所有正则表达式容器都是私有的,以及具有共享容器和锁或 RW 锁的解决方案中,除非非 RW 锁也保护给定正则表达式的操作。如果多场比赛是一个问题,这一切都应该重新考虑。
您可以通过创建关键部分来实现此目的。
#pragma omp critical
{
...some synchronized code...
}
编辑:删除了有关"#pragma omp 原子"的部分,因为它无法以原子方式执行所需的操作。
- 在cuda线程之间共享大量常量数据
- 在c代码之间共享数据的最佳方式
- C++/QT:使用指向私有成员的常量指针作为只读数据共享
- 线程之间的实时数据共享
- 共享 C++ 的数据成员指针
- DLL共享数据的推荐方式是什么
- 两个单独的类不共享相同的数据 C++
- 如何在进程之间共享大量数据而不重复?(国际刑罚委员会)
- 如何在共享库的整个生命周期内存储数据
- 简单使用 std::atomic 在两个线程之间共享数据
- 初始化可变数据结构中的共享指针向量
- 跨线程共享数据集与拆分每个线程的数据
- 如何实现共享数据的复制构造函数
- C++实现相同接口的对象/类之间的数据共享
- 线程之间类的静态数据共享
- OpenMP中类成员变量的数据共享属性
- 多个文件数据共享
- GL顶点数据的QThread数据共享方法
- c++ /Windows多线程同步/数据共享
- bhoc++标签之间的数据共享