1

一定の数の子と一定の深さを持つツリーを構築しようとしています。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);
}
4

1 に答える 1

2

ネストされた並列処理は、ほとんどすべての OpenMP ランタイムでデフォルトで無効になっています。次の 2 つの方法のいずれかで明示的に有効にする必要があります。

  • 電話omp_set_nested(1);
  • 環境変数OMP_NESTEDをに設定しますTRUE

その場合、ネストされた並列処理は必要ない場合があります。スレッドの数が急速に増加し、多くのシステム リソースを消費する可能性があります。むしろ、OpenMP タスクを使用する必要があります。これらは、すべての OpenMP 3.0 準拠のコンパイラでサポートされている必要があります。

于 2012-05-31T07:07:07.643 に答える