我正在尝试构建一个具有固定数量的子项以及固定深度的树。我不完全理解openMP的基础机制。树构造在调用build(root_node, 0)
时开始。现在让我们假设maxDepth
被赋予一个任意数字,maxChildren
等于n
。调用build(root_node, 0)
时,会启动n
个线程。我的印象是每个n
个线程都会创建n
个线程。但是,仔细观察top
表明,线程永远不会超过n
。只有当maxChildren
等于或高于我拥有的核心数时,才能使我的核心饱和。似乎递归中后续级别的parallel
块没有效果,将后续使用的可用线程数限制为初始调用build
时所需的线程。
为什么它会这样?递归中有任何一部分吗?最重要的是,我该怎么做才能解决这个问题?提前谢谢。
void
build(Node* pNode, unsigned int depth)
{
if (depth >= maxDepth)
return;
std::list<Node*> children;
std::list<Node*>::iterator it;
// This loop cannot be parallelized because each call to select_next_node
// is dependent on the previous one
for (unsigned i = 0; i < maxChildren; ++i)
{
Node* const p_candidate_node = select_next_node(...);
if (is_valid(p_candidate_node))
children.push_back(p_candidate_node);
}
#pragma omp parallel private(it)
for (it = children.begin(); it != children.end(); ++it)
#pragma omp single nowait
build(*it, depth + 1);
}
答案 0 :(得分:2)
默认情况下,几乎所有OpenMP运行时都禁用嵌套并行性。您应该通过以下两种方法之一明确启用它:
omp_set_nested(1);
OMP_NESTED
设置为TRUE
在这种情况下,嵌套并行性可能不是您想要的。线程数可能会非常快速地增长并消耗大量系统资源。您应该使用OpenMP任务。所有符合OpenMP 3.0标准的编译器都应该支持它们。