tbb基础之parallel_reduce用法详解

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

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

// parallel_reduction
class SumFoo
{
	float *my_a;

public:
	float sum;
	void operator()( const blocked_range& 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(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执行流程如下图所示:

tbb基础之parallel_reduce用法详解_第1张图片

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

tbb基础之parallel_reduce用法详解_第2张图片



你可能感兴趣的:(SSE_TBB加速编程)