Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenMP共享数据_C++_Openmp_Shared - Fatal编程技术网

C++ OpenMP共享数据

C++ OpenMP共享数据,c++,openmp,shared,C++,Openmp,Shared,我对OpenMP有点陌生,但通常有并行处理的经验。我以前使用过boost::threads,现在我正在使用openmp进行测试 问题是我不知道如何处理共享数据访问,因为我真的不知道openmp在并行循环中对共享数据对象的内部操作 我现在正在做的事情(到目前为止还可以):我使用mmap将文件从磁盘读取到内存中。在内存映射部分之后,我收到一个关于char的指针 OpenMP现在可以在OpenMP并行for循环中使用此指针,并在线程之间共享数据。我现在可以在映射和共享文件中搜索正则表达式匹配项,多个线

我对OpenMP有点陌生,但通常有并行处理的经验。我以前使用过
boost::threads
,现在我正在使用openmp进行测试

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

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

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

我将这个列表(包含正则表达式的向量)设置为openmp循环中的私有列表,因此每个线程都有自己的列表副本

问题来了:

为了显著提高应用程序的性能,我需要能够在(regex-)项与字符串匹配后从此向量中删除它们

现在所有其他活动线程也需要尽快从列表中删除此项

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

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


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

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

#pragma omp critical
{
   ...some synchronized code...
}
编辑:
删除了有关“#pragma omp atomic”的部分,因为它无法自动执行所需的操作。

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

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

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

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

我认为以下措施可能会更好:

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

在这个方案中,存在读/写标志的竞争:标志可能会在下一个线程将其读为“有效”时被设置为“擦除”。因此,两个不同的线程可能会同时为同一个正则表达式找到匹配项。然而,我相信这个问题存在于所有正则表达式容器都是私有的当前解决方案中,也存在于具有共享容器和锁或RW锁的解决方案中,除非非RW锁也保护具有给定正则表达式的操作。如果存在多个匹配项的问题,则应重新考虑。

您是否有一个最小的示例来演示该问题?
#pragma omp atomic
在允许的表达式中非常有限。您给出的示例不符合OpenMP规范。我建议你从答案中删除相应的部分。