如何在openMP(C ++)中从线程生成子线程

时间:2012-05-31 00:01:26

标签: c++ multithreading parallel-processing openmp

我正在尝试构建一个具有固定数量的子项以及固定深度的树。我不完全理解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);
}

1 个答案:

答案 0 :(得分:2)

默认情况下,几乎所有OpenMP运行时都禁用嵌套并行性。您应该通过以下两种方法之一明确启用它:

  • 致电omp_set_nested(1);
  • 将环境变量OMP_NESTED设置为TRUE

在这种情况下,嵌套并行性可能不是您想要的。线程数可能会非常快速地增长并消耗大量系统资源。您应该使用OpenMP任务。所有符合OpenMP 3.0标准的编译器都应该支持它们。