2

C++でポストオーダーツリートラバーサルを実行したいと思います。ツリーが非常に深くなる可能性があるため、再帰を使用できません(スタックを使い果たします)。代わりに、std::stack<...>すべてをヒープに配置するを作成し、関数呼び出しではなく、whileループでツリーをトラバースします。これはうまくいきます。

ここで、TBBを使用してプロセス全体を並列化したいと思います。私はtask_groupすべてのノードでを作成しfunctor、その子のそれぞれで同じものを実行することを考えていました。しかし、これは以前と同じツリーの深さの問題にfunctor遭遇することになります。最も深いパスの各ノードでを実行すると、すべてがなくなるまでスタックから何かが失われます。

この問題を解決する方法はありますか?それとも私はすべてを想像していますか?task_group::wait()この問題を回避 する魔法が背後にありますか?

4

2 に答える 2

1

TBBのドキュメントから(暗黙の継続について):

親がブロックしているため、そのスレッドのスタックはまだポップできません。スレッドは、継続的にスチールとブロックを行うと、スタックが際限なく大きくなる可能性があるため、実行する作業に注意する必要があります。

これは正確にはそうではありませんが、TBB が現在ブロックされているタスクのスタックを空にするためにスタック マジックを使用していないことを示しています。これは、暗黙的な継続を使用すると、少し後でスタック オーバーフローが発生する (複数のスレッドのスタックに分散される) ことを意味します。

明示的な継続を使用すると問題が解決する可能性がありますが、それはスレッド スケジューラの内部 TBB 実装に大きく依存します (ドキュメント化されていません)。それが正しく動作する可能性はかなりあります - 知る唯一の方法は、TBB ソースを調べてタスクがどのように処理されるかを確認するか、小さなスタックで簡単なテスト プログラムを作成し、単純なものでそれを使い果たすことができるかどうかを確認することです。

于 2011-10-13T22:40:16.507 に答える
0

これには継続を使用する必要があることを確認するコメントだけです。task_group::wait がスタックを消費するのを防ぐ魔法のようなものは何もありません。

task_group は ppl にあり、msdn ブログで説明され、ppl サンプル パックで利用可能なタスクの継続を使用できます。

于 2011-10-14T22:28:36.590 に答える