TBB task_groups没有使用堆栈

时间:2011-10-13 19:36:50

标签: c++ tree traversal tbb

我想在C ++中执行一个后序树遍历。树可以很深,我不能使用递归(它耗尽堆栈)。相反,我创建了一个std::stack<...>,它将所有内容放在堆上,并在while循环中遍历树而不是函数调用。这很有效。

现在我想使用TBB并行化整个过程。我想在每个节点上创建一个task_group,并在每个节点上运行相同的functor。但是我发现这会遇到与之前的树深度相同的问题:在最深路径的每个节点上运行functor会从堆栈中消耗掉一些东西,直到整个过程耗尽。 / p>

有没有办法摆脱这个问题?或者我想象整件事; task_group::wait()背后是否​​存在一些可以避免此问题的魔法?

2 个答案:

答案 0 :(得分:1)

来自TBB文档(关于隐式延续):

  

因为父块阻塞,所以它的线程堆栈无法弹出。   线程必须小心它需要做什么工作,因为   持续窃取和阻塞可能导致堆栈增长   没有约束。

这与此不完全相同,但它表明TBB没有使用任何堆栈魔法为当前被阻止的任务清空堆栈。这意味着当使用隐式延续时,你会稍后得到堆栈溢出(在多个线程的堆栈中扩展)。

使用显式延续可能会解决问题,但这在很大程度上取决于线程调度程序的内部TBB实现(未记录)。它有可能正常工作 - 唯一可以知道的方法是查看TBB源代码,看看如何处理任务,或者用简单的堆栈编写简单的测试程序,并查看简单的东西是否能够耗尽它。

答案 1 :(得分:0)

只是评论验证您需要使用延续。没有什么神奇的task_group :: wait会阻止它消耗堆栈。

task_group位于ppl中,您可以使用msdn blog中描述的任务延续,并在ppl示例包中提供。