2012-12-01 47 views
0

我使用英特爾TBB parallel_for時加快for循環做一些計算:更高的核心負載英特爾TBB

tbb::parallel_for(tbb::blocked_range<int>(0,ListSize,1000),Calc); 

Calc是一個類的對象doCalc

class DoCalc 
{ 
vector<string>FileList; 
public: 
    void operator()(const tbb::blocked_range<int>& range) const{ 
    for(int i=range.begin(); i!=range.end();++i){ 
    //Do some calculations 
    } 
    } 
    DoCalc(vector<string> ilist):FileList(ilist){} 
}; 

大約需要當我使用for循環的標準串行格式時約60秒, 20秒時,我使用TBB的parallel_for完成工作。使用標準版時,我的i5 CPU的每個核心的負載大約爲15%(根據Windows任務管理器)和非常不均勻的,大約。使用parallel_for時爲50%且非常均勻。

我想知道使用parallel_for時是否有可能獲得更高的核心負載。除了grain_size還有其他參數嗎?如何在不改變for循環內的操作的情況下提高parallel_for的速度(這裏是//在上面的代碼示例中進行一些計算)。

回答

0

由於@Eugene越野車已經建議,您可能需要使用auto_partitioner(這是從TBB 2.2版默認值)範圍內的自動chuncking:

tbb::parallel_for(tbb::blocked_range<int>(0,ListSize),Calc,tbb:auto_partitioner()); 

我假設你的i5 CPU的有4核心,所以你可以獲得3(60s => 20s)的加速,這已經「相當不錯」了,因爲並行化可能會有一定的開銷。一個問題可能是你的CPU的內存帶寬的最大限制是由3個線程飽和 - 或者你可能有很多的分配/解除分配,這些分配/解除分配必須在具有標準內存管理器的線程之間進行同步。在內循環中沒有太多代碼改變的情況下解決這個問題的一個技巧可能是使用線程本地分配器,例如,對於文件清單:

vector<string,tbb:scalable_allocator<string>> FileList; 

請注意,你應該嘗試的TBB :: scalable_allocator在環太中使用的所有其他容器中,爲了使您的並行加速比接近核心數量,4

1

grainize參數是可選的。如果未指定grainizee,則應將分區程序提供給算法模板。分區程序是指導區域分塊的對象。 auto_partitioner提供了一種替代方法,試探性地選擇粒度,以便不必指定粒度。啓發式嘗試限制開銷,同時仍然提供充足的負載平衡機會。

轉到tbb網站獲取更多信息。 www.threadingbuildingblocks.org

0

您的問題的答案還取決於您的算法中內存訪問和計算之間的比率。如果你對很多數據做很少的操作,你的問題就是內存限制,這會限制核心負載。另一方面,如果你用很少的數據計算大量數據,你的改進機會就會更好。