2012-05-31 79 views
1

我正在尝试构建一个固定数量的子树以及固定深度的树。我不完全了解openMP的基本机制。树木施工在拨打build(root_node, 0)后开始。现在让我们假设maxDepth被赋予一个任意数字,并且maxChildren等于n。当调用build(root_node, 0)时,会启动n线程。我的印象是,这些n线程中的每一个都会创建n线程。但仔细观察top发现,线程永远不会超过n。只有当maxChildren等于或高于我拥有的核心数量时,我才可以饱和我的核心。看起来在递归中的后续级别的parallel块没有效果,将后续使用的可用线程的数量限制为初始调用build所需的。如何在openMP中产生线程中的子线程(C++)

它为什么会这样?这个递归是否有任何部分?而最重要的是,我能做些什么来补救呢?提前致谢。

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); 
} 

回答

2

默认情况下,在几乎所有OpenMP运行时都禁用了嵌套并行。

  • 呼叫omp_set_nested(1);
  • 设置的环境变量OMP_NESTEDTRUE

嵌套并行操作可能不是你在这种情况下,想要的东西:你应该明确地由这两个方法之一启用它。线程数量可能增长非常快,并消耗大量系统资源。您应该使用OpenMP任务。它们应该受到所有OpenMP 3.0兼容编译器的支持。

+0

启用嵌套并行确实消耗了太多的资源,我一直使用'maxDepth = 10'和'maxChildren = 2'得到“线程创建失败:资源暂时不可用”的错误。再次感谢你的智慧! –

+0

有没有一种方法可以限制可以生成的最大线程数量,而无需显式设置环境变量? –

+1

您可以通过设置“OMP_NUM_THREADS”环境变量来指定最大线程数。它的值是逗号分隔的正数列表,它指定了每个嵌套级别使用的线程数量,例如, 'export OMP_NUM_THREADS = 4,2,2'表示在基本级别有4个线程,然后对于第一个和第二个嵌套级别最多有2个线程。 –