2011-10-13 63 views
2

我想在C++中執行後序樹遍歷。樹可以很深,我不能使用遞歸(它耗盡了堆棧)。相反,我創建了一個將所有內容放在堆上的std::stack<...>,並在while循環中遍歷樹,而不是使用函數調用。這很好。TBB task_groups不使用堆棧

現在我想使用TBB並行化整個過程。我正在考慮在每個節點上創建一個task_group,並在其每個子節點上運行相同的functor。但在我看來,這會遇到同樣的問題,就像我以前的樹深度一樣:在最深的路徑的每個節點上運行functor將從堆棧中消耗掉一些東西,直到整個東西用完。

有沒有辦法解決這個問題?還是我想象整個事情; task_group::wait()背後有什麼魔法可以避免這個問題?

回答

1

從TBB資料(有關隱式續):

因爲父塊,它的線程的堆棧還不能彈出。 線程必須小心它的工作原理,因爲 不斷的偷竊和阻塞可能會導致堆棧無限制地增長 。

這並不完全是這樣,但它表明TBB沒有使用任何堆棧魔術來清空當前被阻塞的任務的堆棧。這意味着當使用隱式延續時,你會稍後得到堆棧溢出(在多線程堆棧之間擴展)。

使用顯式延續可能會解決問題,但這在很大程度上取決於線程調度程序的內部TBB實現(沒有記錄)。有一個公平的機會,它會正常工作 - 要知道的唯一方法是要麼通過TBB來源看,要麼看到如何處理任務,要麼用小堆棧編寫簡單的測試程序,看看簡單的東西是否會耗盡它。

+0

感謝您的回答。我認爲明確的延續是要走的路。如果我理解正確傳遞TBB教程的延續,它應該避免我的問題。我想,是時候進行實驗了。 – foxcub

+0

如果您有任何實驗結果,請將它們發佈到此處 - 我也是qurious的;) –

0

只是一個評論,驗證你將需要使用此延續。 task_group :: wait沒有什麼不可思議的,它會阻止它消耗堆棧。

task_group在ppl中,您可以使用msdn blog中描述的任務延續,並在ppl示例包中提供。

+0

我對Miscrosoft的世界一無所知。 PPL和TBB之間是否有聯繫? – foxcub