我正在查看page上的示例,其中显示了如何以命令形式调用parallel_reduce
。这个例子的副本如下:
struct Sum {
float value;
Sum() : value(0) {}
Sum( Sum& s, split ) {value = 0;}
void operator()( const blocked_range<float*>& r ) {
float temp = value;
for( float* a=r.begin(); a!=r.end(); ++a ) {
temp += *a;
}
value = temp;
}
void join( Sum& rhs ) {value += rhs.value;}
};
float ParallelSum( float array[], size_t n ) {
Sum total;
parallel_reduce( blocked_range<float*>( array, array+n ),
total );
return total.value;
}
我的问题是 - 我们为什么需要float temp
身体中的operator()
变量?如果求和将直接与value
数据成员一起使用,可能会发生什么:
for( float* a=r.begin(); a!=r.end(); ++a ) value += *a;
答案 0 :(得分:3)
直接应用它将起作用,因为同一个线程同时使用该类的每个实例。
但直接使用此变量可能会阻止编译器对循环进行矢量化。我通过缓存r.end()更进一步使用这个逻辑,因为如果没有正确内联,它也可以打破向量化。虽然它与TBB本身没有直接关系,但只是一般的C ++优化技巧。