C++11 OpenMP并行区域之间的共享内存是否不一致?
我正在写一个工具来测试一些图形算法。在特定条件下,该工具必须遍历图形中的所有边,并在任意一端标记节点。然后它必须遍历所有节点,确保它们都被标记。代码应该很简单,但我有一些并发性问题 这是我的密码:C++11 OpenMP并行区域之间的共享内存是否不一致?,c++11,concurrency,openmp,C++11,Concurrency,Openmp,我正在写一个工具来测试一些图形算法。在特定条件下,该工具必须遍历图形中的所有边,并在任意一端标记节点。然后它必须遍历所有节点,确保它们都被标记。代码应该很简单,但我有一些并发性问题 这是我的密码: #pragma omp parallel for reduction(+:seen_edges) default(shared) for (size_t i = 0; i < n_edges; i++) { int64_t v0 = node_left(edges[i]), v1 = n
#pragma omp parallel for reduction(+:seen_edges) default(shared)
for (size_t i = 0; i < n_edges; i++)
{
int64_t v0 = node_left(edges[i]), v1 = node_right(edges[i]);
// Do some work...
// This is where I mark nodes if the other end of the edge corresponds to the parent array
if (v0 != v1)
{
if(parents[v0] == v1)
reached[v0] = true;
if(parents[v1] == v0)
reached[v1] = true;
}
// Do more work...
}
#pragma omp parallel for default(shared)
for (size_t i = 0; i < n_nodes; i++)
{
if (i != source && !reached[i])
error("No traversed edge leading to node", i, &n_errors);
}
#pragma omp parallel for reduction(+:seed_edges)默认值(共享)
对于(大小i=0;i
到达的数组被初始化为false
我可以保证在我使用的输入上,所有节点都应该被标记,因此不应该打印错误。但是,有时某些节点仍然未标记
我认为OpenMP并行区域之间共享的内存应该是一致的,并且我从未将reach
中的任何元素设置为false,除非是在初始化时。在检查所有边(以及此测试输入上标记的所有节点)之前,第一个区域末端的隐式屏障应防止任何线程进入第二个区域
我看到了两种可能的选择,但没有进一步的解释:
true
true
,但第二个并行区域中的线程之间内存不一致。这在OpenMP中会发生吗编辑:
//Do work
部分不使用到达的
数组,并且父项
在程序中从不修改。最有可能的情况是,竞争条件在//Do more work…
部分中的某个地方。注释部分不会以任何方式接触到达的
数组,并且在程序中的任何地方都不会修改父项。我将编辑我的问题以添加此信息。共享数据必须更新,并且更新在屏障或连接/分叉后对所有线程可见。你还有别的问题。也许值得使用一个种族检测工具,比如Intel Parallel Inspector@Andrei是一个没有闭环的图?实际上,在我看来,两个单独的线程可以将它们的v0
或v1
设置为与另一个线程相同,然后更改到达的
数组,从而造成这种不一致性。回答你名义上的问题:不,这不能前后矛盾。我并不是说达到了,
在//做更多的工作…
。我宁愿声称有某种东西阻止if
条件为真,因此它阻止达到[…]
设置为真。我支持Jim Cownie-通过线程检查工具运行程序。