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

2023-12-14

我正在尝试构建一棵具有固定数量的子级和固定深度的树。我不完全理解 openMP 的底层机制。调用后开始构建树build(root_node, 0)。现在我们假设maxDepth给定一个任意数并且maxChildren等于n. When 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);
}

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

  • call omp_set_nested(1);
  • 设置环境变量OMP_NESTED to TRUE

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从 openMP 中的线程生成子线程 (C++) 的相关文章

随机推荐