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,除非是在初始化时。在检查所有边(以及此测试输入上标记的所有节点)之前,第一个区域末端的隐式屏障应防止任何线程进入第二个区域

我看到了两种可能的选择,但没有进一步的解释:

  • 某种数据竞赛正在进行。但因为我从未将元素设置回false,即使多个线程试图同时写入一个位置,该元素最终是否会变成
    true
  • 元素设置为
    true
    ,但第二个并行区域中的线程之间内存不一致。这在OpenMP中会发生吗
  • 如果有人有任何见解,我将不胜感激。干杯


    编辑:
    //Do work
    部分不使用
    到达的
    数组,并且
    父项
    在程序中从不修改。

    最有可能的情况是,竞争条件在
    //Do more work…
    部分中的某个地方。注释部分不会以任何方式接触
    到达的
    数组,并且在程序中的任何地方都不会修改父项。我将编辑我的问题以添加此信息。共享数据必须更新,并且更新在屏障或连接/分叉后对所有线程可见。你还有别的问题。也许值得使用一个种族检测工具,比如Intel Parallel Inspector@Andrei是一个没有闭环的图?实际上,在我看来,两个单独的线程可以将它们的
    v0
    v1
    设置为与另一个线程相同,然后更改
    到达的
    数组,从而造成这种不一致性。回答你名义上的问题:不,这不能前后矛盾。我并不是说
    达到了
    //做更多的工作…
    。我宁愿声称有某种东西阻止
    if
    条件为真,因此它阻止
    达到[…]
    设置为
    真。我支持Jim Cownie-通过线程检查工具运行程序。