【问题标题】:How to spawn subthreads from threads in openMP (C++)如何从 openMP (C++) 中的线程生成子线程
【发布时间】:2012-05-31 00:01:26
【问题描述】:

我正在尝试构建具有固定数量的子节点和固定深度的树。我并不完全理解 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);
}

【问题讨论】:

    标签: c++ multithreading parallel-processing openmp


    【解决方案1】:

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

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

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

    【讨论】:

    • 启用嵌套并行确实消耗了太多资源,我不断收到 maxDepth = 10maxChildren = 2 的“线程创建失败:资源暂时不可用”错误。再次感谢您的智慧!
    • 有没有办法限制在不显式设置环境变量的情况下可以产生的最大线程数?
    • 可以通过设置OMP_NUM_THREADS环境变量来指定最大线程数。它的值是一个逗号分隔的正数列表,指定在每个嵌套级别使用的线程数,例如export OMP_NUM_THREADS=4,2,2 表示基本级别有 4 个线程,然后第一和第二个嵌套级别最多有 2 个线程。
    • 谢谢!当我获得足够的声望时,我会 +1。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 2017-11-11
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多