2012-12-01 46 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

您的问题的答案还取决于您的算法中内存访问和计算之间的比率。如果你对很多数据做很少的操作,你的问题就是内存限制,这会限制核心负载。另一方面,如果你用很少的数据计算大量数据,你的改进机会就会更好。