[英]OpenMP shared data
我对OpenMP有点新,但总体上有并行处理的经验。 之前我使用过boost::threads
,现在我正在使用openmp进行测试。
问题是我不知道如何处理共享数据访问,因为我真的不知道openmp在内部对并行循环内的共享数据对象做了什么。
我现在正在做什么(这是迄今为止的工作):我使用mmap将文件从磁盘读入内存。 我在内存映射部分后面收到一个关于char的指针。
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
的好处是简单性和在已知并行区域由单个线程执行时忽略pragma的能力。 缺点仅适用于单个并行区域,并且在该区域内具有全局效果:没有其他线程可以执行该区域中的任何其他关键部分。
OpenMP锁定例程与大多数其他可用锁类似,例如pthreads或Boost(RAII除外)。 您初始化一个锁定对象,然后使用它来保护某些关键部分,并在不必要时销毁它。 这些锁可用于保护对来自不同并行区域的数据的访问,构建分布式锁定方案等; 但总会产生一定的开销,与#pragma omp critical
相比,肯定使用起来更“毛茸茸”。
但是,我会挑战并行解决方案的设计。 从向量中间擦除元素会使所有迭代器失效,并移动元素。 擦除被认为是一种罕见的操作(否则,即使在我认为的串行代码中,矢量的选择也会有问题),但由于上述影响,你必须保护矢量的所有读取,这可能是昂贵的。 读/写锁可以带来一些缓解,但这些在OpenMP中不可用,因此您需要使用特定于平台的接口或第三方库。
我认为以下内容可能会更好:
在这种方案中,存在用于读/写标志的竞赛:在下一个被另一个线程读取为“有效”的时刻,可以将标志设置为“擦除”。 结果,两个不同的线程可以同时找到相同正则表达式的匹配。 但是我认为这个问题存在于当前的解决方案中,其中所有正则表达式容器都是私有的,以及具有共享容器和锁或RW锁的解决方案,除非非RW锁也保护使用给定正则表达式的操作。 如果多个匹配是一个问题,那么应该重新思考。
您可以通过创建关键部分来实现此目的。
#pragma omp critical
{
...some synchronized code...
}
编辑:删除了关于'#pragma omp atomic'的部分,因为它无法自动执行所需的操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.