【问题标题】:Higher core load Intel TBB更高的核心负载英特尔 TBB
【发布时间】:2012-12-01 20:42:47
【问题描述】:

我正在使用 Intel TBB parallel_for 来加速 for 循环进行一些计算:

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 秒。当我使用 TBB 的 parallel_for 完成工作时,需要 20 秒。使用标准时,我的 i5 CPU 的每个内核的负载约为。 15%(根据 Windows 任务管理器)并且非常不均匀,大约为 15%。使用 parallel_for 时为 50% 且非常均匀。

我想知道在使用 parallel_for 时是否可以获得更高的核心负载。除了grain_size还有其他参数吗?如何在不更改 for 循环中的操作的情况下提高 parallel_for 的速度(此处为//在上面的代码示例中进行一些计算)。

【问题讨论】:

    标签: c++ for-loop parallel-processing intel tbb


    【解决方案1】:

    grainsize 参数是可选的。如果未指定 grainsizee,则应为算法模板提供分区器。分区器是指导范围分块的对象。 auto_partitioner 提供了一种替代方法,它可以启发式地选择粒度大小,这样您就不必指定一个。启发式尝试限制开销,同时仍提供充足的负载平衡机会。

    请访问 tbb 网站了解更多信息。 www.threadingbuildingblocks.org

    【讨论】:

      【解决方案2】:

      正如@Eugene Roader 已经建议的那样,您可能希望使用 auto_partitioner(这是 TBB 版本 2.2 的默认设置)来自动分块范围:

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

      我假设您的 i5-CPU 有 4 个内核,因此您可以获得 3(60 秒 => 20 秒)的加速,这已经“相当不错”了,因为并行化中可能存在某些开销。一个问题可能是 CPU 的内存带宽的最大限制,它被 3 个线程饱和 - 或者您可能有很多分配/解除分配,这些分配/取消分配是/必须在线程之间与标准内存管理器同步。在内部循环中没有太多代码更改的情况下解决此问题的一个技巧可能是使用线程本地分配器,例如对于文件列表:

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

      请注意,您也应该为循环中使用的所有其他容器尝试 tbb::scalable_allocator,以使您的并行化加速更接近内核数 4。

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 2023-03-25
          • 2011-10-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多