TBB parallel_reduce - 需要更好地理解 "Developer Reference" 中的示例
TBB parallel_reduce - need better understanding of example from the "Developer Reference"
我正在查看 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;
}
我的问题是 - 为什么我们在 operator()
正文中需要 float temp
变量?如果求和直接与 value
数据成员一起工作,可能会发生什么:
for( float* a=r.begin(); a!=r.end(); ++a ) value += *a;
直接应用它会起作用,因为 class 的每个实例同时被一个线程使用。
但直接使用此变量可能会阻止编译器对循环进行矢量化。我将通过缓存 r.end() 来进一步处理此逻辑,因为如果它没有正确内联,它也会破坏矢量化。虽然,它与 TBB 本身没有直接关系,只是一般的 C++ 优化技巧。
我正在查看 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;
}
我的问题是 - 为什么我们在 operator()
正文中需要 float temp
变量?如果求和直接与 value
数据成员一起工作,可能会发生什么:
for( float* a=r.begin(); a!=r.end(); ++a ) value += *a;
直接应用它会起作用,因为 class 的每个实例同时被一个线程使用。
但直接使用此变量可能会阻止编译器对循环进行矢量化。我将通过缓存 r.end() 来进一步处理此逻辑,因为如果它没有正确内联,它也会破坏矢量化。虽然,它与 TBB 本身没有直接关系,只是一般的 C++ 优化技巧。