2012-04-03 133 views
4

我有一個關於微軟PPL庫和一般的並行編程的問題。我正在使用FFTW執行64 x 64 x 64 FFT和反FFT的大集(100,000)。在我當前的實現中,我使用並行for循環並在循環內分配存儲陣列。我注意到在這些情況下,我的CPU使用率只有60-70%左右。 (注意這比我已經測試過的FFTW提供的內置線程化FFT更好的利用率)。由於我正在使用fftw_malloc,是否有可能發生過度鎖定,導致無法使用?線程ID與PPL和並行內存分配

鑑於此,是否建議在主處理循環之前爲每個線程預先分配存儲陣列,因此在循環本身內不需要鎖定?如果是這樣,那麼MSFT PPL庫怎麼可能呢?我以前一直在使用OpenMP,在這種情況下,使用提供的函數獲得線程ID已經足夠簡單了。然而,我還沒有在PPL文檔中看到類似的功能。

回答

2

我只是回答這個問題,因爲沒有人發佈任何內容。

如果需要大量鎖定,互斥鎖(e)會對性能造成嚴重破壞。此外,如果需要大量內存(重新)分配,那麼也會降低性能並將其限制到您的內存帶寬。就像你說的那樣,稍後線程操作的預分配可能是有用的。但是,這要求您有固定的線程數,並且在所有線程上均衡分佈工作負載。

關於PPL thread_id函數,我只能講英特爾TBB,但是它應該與PPL非常相似。 TBB - 我想PPL也不是直接講話,而是談論任務,TBB的目標是將這些底層細節從用戶中抽象出來,因此它不提供thread_id函數。

+0

感謝您的快速回復。我同意你的看法,瓶頸似乎與大量內存分配有關;隨着FFT大小的減小,相對並行加速度增加(例如,16×16×16給出了幾乎線性的加速以及100%的利用率)。知道PPL是一個基於任務的框架,你知道有什麼方法可以爲每個任務做內存分配嗎? (並不一定是每個循環迭代,就像現在所做的那樣)基本上,每個線程/任務都有一組動態分配的私有數據。 – 2012-04-04 10:17:01

+0

我對這些框架的天真提前表示歉意。我的背景是工程,而不是CS。 – 2012-04-04 10:21:44

+0

@KyleLynch好吧,假設你的工作量是平衡的,我可以考慮以下幾點:儘可能保持粒度的大小,然後在你的工作者分配循環之前的內存。編輯:我只是檢查了ppl :: parallel_for out和界面確實有點不同於tbb。 TBB的優勢在於你可以在一個範圍內更好地工作。對於PPL中的相同行爲,你可能不得不寫一個包裝函數。我希望代碼解釋我的意思。 http://pastebin.com/Tg4FL6KB – inf 2012-04-04 12:01:30

0

使用PPL我有一個應用程序的良好性能,通過使用Concurrency::combinable來保存包含每個線程分配的內存的結構進行大量分配。

實際上,您不必預先分配,您可以使用->local()檢查可組合變量的值,如果它爲空則分配它。下次這個線程被調用時,它已經被分配了。

當然,你必須釋放內存,當所有任務完成後可使用來實現:用類似 :

combine_each([](MyPtr* p){ delete p; });