如何从OpenMP(C ++)中的线程产生子线程 [英] How to spawn subthreads from threads in openMP (C++)

查看:320
本文介绍了如何从OpenMP(C ++)中的线程产生子线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试建立一棵具有固定数量的孩子和固定深度的树.我不完全了解openMP的基本机制.调用build(root_node, 0)后,树的构造开始.现在,让我们为maxDepth赋予一个任意数字,并且maxChildren等于n.调用build(root_node, 0)时,将启动n线程.我的印象是,每个n线程都会创建n线程.但是,仔细观察top会发现,n线程的数量从来没有超过.仅当maxChildren等于或大于我拥有的内核数时,我才能使内核饱和.递归的后续级别中的parallel块似乎没有效果,将可供后续使用的可用线程数限制为对build的初次调用所需的线程数.

I am trying to build a tree with a fixed number of children as well as a fixed depth. I do not fully understand the underlying mechanics of openMP. Tree construction begins upon calling build(root_node, 0). Now let's suppose that maxDepth is given an arbitrary number and that maxChildren is equal to n. When build(root_node, 0) is called, n threads are launched. I was under the impression that each of these n threads would create n threads. However, careful observation of top revealed that there are never more than n threads. I can saturate my cores only when maxChildren is equal or higher than the number of cores I have. It seems that the parallel blocks in subsequent levels in the recursion have no effet, limiting the number of available threads for subsequent use to what was needed in the initial call to build.

为什么它会表现这种方式?递归在这方面有什么作用吗?最重要的是,我可以采取什么措施来解决这个问题?预先感谢.

Why does it behave this way? Has the recursion any part in this? And most importantly, what can I do to remedy this? Thanks in advance.

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运行时中,嵌套并行操作都是禁用的.您应该通过以下两种方法之一显式启用它:

Nested parallelism is disabled by default in almost all OpenMP run-times. You should explicitly enable it by one of those two methods:

  • 致电omp_set_nested(1);
  • 将环境变量OMP_NESTED设置为TRUE
  • call omp_set_nested(1);
  • set environment variable OMP_NESTED to TRUE

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

Nested parallelism might not be what you want in that case. The number of threads could grow very fast and consume lots of system resources. You should rather use OpenMP tasks. They should be supported by all OpenMP 3.0 compliant compilers.

这篇关于如何从OpenMP(C ++)中的线程产生子线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆