无法理解 OpenMP 代码中的一些意外行为
Posted
技术标签:
【中文标题】无法理解 OpenMP 代码中的一些意外行为【英文标题】:Trouble understanding some unexpected behaviour in code with OpenMP 【发布时间】:2019-11-08 22:01:48 【问题描述】:关于 OpenMP 并行化的问题。我在下面包含了我的函数的精简版本。问题是,for 循环的内容并未针对 uiIndex 的所有值进行评估,尽管并非总是如此。
-
我使用缓冲区 vec_succ_status 检查是否所有的 uiIndex 值都得到了评估。事实证明不是。
我的代码没有崩溃,它只是从函数 compute_Lagr_shortest_paths_from_source 中退出,没有遇到下面函数定义中的任何 exit(-1) 语句。
我在 Ubunutu 14 上使用 g++ 7.4.0 版本,每次失败时,都会跳过一个 uiIndex 值。函数无法评估的 uiIndex 没有一致性。
对于我一直在测试的程序,vec_group 的大小始终为 1,因此只有 for 循环中的第一个 if 语句会计算。
在我的主函数中,我包含了 omp_set_num_threads(4) 行。除此之外,我没有为 OpenMP 设置任何其他设置(例如调度程序类型)。
另外,我可以保证没有 2 个 uiIndex 值会导致相同的 uiRobot 值,因此不会有 2 个线程必须在函数的有效期内访问相同的 vec_cf_graphs[uiRobot] 数组。
我想知道我是否对 OpenMp 做出了一些错误的假设。我要求在所有线程之间共享所有对象,例如 vec_cf_graphs、vec_succ_status。我想知道是否需要明确提及它们是共享的,因为它通常是推荐的方法。无论如何,我认为我实施的方式也足够了。但是,对我来说,某些 uiIndex 值可以完全跳过,这似乎很奇怪。我必须指出,我反复调用显示的函数,但只是有时某些 uiIndex 值会从评估中跳过。如果有人可以指出我的方法的潜在问题,那就太好了。我很高兴提供更多信息。谢谢。
bool compute_Lagr_shortest_paths_from_source(std::vector<Robot_CF_Graph>& vec_cf_graphs, const std::vector<std::vector<size_t>>& vec_robot_groups)
size_t uiIndex;
std::vector<bool> vec_succ_status(vec_robot_groups.size(), false);
#pragma omp parallel for default(shared) private(uiIndex)
for(uiIndex = 0; uiIndex < vec_robot_groups.size(); uiIndex++)
vec_succ_status[uiIndex] = false;
const auto& vec_group = vec_robot_groups[uiIndex];
if(1 == vec_group.size())
size_t uiRobot = vec_group[0];
vec_cf_graphs[uiRobot].compute_shortest_path("ABC");
vec_succ_status[uiIndex] = true;
else
std::cout<< "Tag: Code should not have entered this block"<<endl;
exit(-1);
if(false == vec_succ_status[uiIndex])
std::cout<< "It is not possible for this to happen \n";
exit(-1);
return true;
【问题讨论】:
也许还值得一提的是,exit(-1)
应该在 parallel for
构造中被避免。我很惊讶编译器没有警告你,因为我记得如果你使用return
,它甚至无法编译。
【参考方案1】:
您同时写信给vector<bool>
,这不是“正常”vector
。它具有内部内存优化。这是未定义的行为。
在此处查看详细推理:
Write concurrently vector<bool>
vector<bool>
与其他vector
s 有何不同,请参见此处:
https://en.cppreference.com/w/cpp/container/vector_bool
仅使用vector<char>
与 0 或 1 代表真或假是解决此问题的最简单方法。如果您想拥有更优雅的代码,此处讨论了其他选项:
Alternative to vector<bool>
【讨论】:
以上是关于无法理解 OpenMP 代码中的一些意外行为的主要内容,如果未能解决你的问题,请参考以下文章