tbb基础之parallel_reduce用法详解

来源:互联网 发布:湖南省地质测绘院 知乎 编辑:程序博客网 时间:2024/05/24 01:26

       对一组数据执行诸如sum, max, min等操作被称为reduction operation。对一组数据并行执行reduction操作可能由于四舍五入导致不同的结果,如 A+B+C+D,串行执行的顺序为(((A+B)+C)+D),而并行执行的顺序可能为((A+B)+(C+D))。

        首先,我们还是来看一个例子:

// parallel_reductionclass SumFoo{float *my_a;public:float sum;void operator()( const blocked_range<size_t>& range){float *a = my_a;for ( size_t i = range.begin(); i!=range.end(); ++i){sum += a[i];}}SumFoo(SumFoo& x, tbb::split):my_a(x.my_a),sum(0){}void join(const SumFoo& y){sum += y.sum;}SumFoo( float * a):my_a(a),sum(0){}};float ParallelSumFoo(  float * fArray, size_t nSize){SumFoo sf(fArray);parallel_reduce( blocked_range<size_t>(0, nSize, 100), sf);return sf.sum;}

       通过上面的例子知道: parallel_reduce的定义与parallel_for类似,但parallel_reduce却与其也有很大的不同点:

        1)operator()是非const

        parallel_reduce必须对SumFoo::sum进行更新,以便后面执行join()时使用。

        2)SumFoo有一个带有split类的构造函数

         带有split类的SumFoo构造函数,split参数用于原对象的引用,用于区分copy构造函数。

        3)join()操作

           当任何一个subtask执行完成时就会调用join()方法,该方法将subtask执行完的结果merge到main body中。

parallel_reduce执行流程如下图所示:


具体来说就是:当任务调度器发现有可供调度的工作线程时,parallel_reduce就调用代用split的构造函数为处理器创建一个子任务(Invoking the splitting constructor to create a subtask for the processor);当子任务执行完成,parallel_reduce则调用join()方法累加子任务的结果。




0 0
原创粉丝点击