big*_*ega 0 c++ parallel-processing tbb openmp
我正在尝试使用英特尔TBB parallel_reduce来获取由双精度组成的数组元素的总和.但是,与OpenMP减少实现相比,结果是不同的.
这是OpenMP的一个:
double dAverageTemp = 0.0;
#pragma omp parallel for reduction(+:dAverageTemp)
for (int i = 0; i < sCartesianSize; i++)
dAverageTemp += pdTempCurr[i];
Run Code Online (Sandbox Code Playgroud)
此代码返回正确的值"317.277 493 "; 但是这个TBB代码:
double dAverageTemp = tbb::parallel_reduce(tbb::blocked_range<double*>(pdTempCurr, pdTempCurr + sCartesianSize - 1),
0.0,
[](const tbb::blocked_range<double*> &r, double value) -> double {
return std::accumulate(r.begin(), r.end(), value);
},
std::plus<double>()
);
Run Code Online (Sandbox Code Playgroud)
坚持认为结果是"317.277 193 ".
我在这里错过了什么?
虽然关于求和顺序的所有注释都是完全正确的,但这里的简单事实是你的代码中有一个错误.所有std::,thrust::和tbb::算法或构造遵守到同样的理念,当涉及到限定范围,其是从第一个元素,以指示采取第一元件不采取,像在for ( auto it = v.begin(); it < v.end(); it++)
因此,在这里,你的代码tbb::blocked_range应该是pdTempCurr + sCartesianSize,而不是pdTempCurr + sCartesianSize - 1.
它应该成为:
double dAverageTemp = tbb::parallel_reduce(tbb::blocked_range<double*>(pdTempCurr, pdTempCurr + sCartesianSize ),
0.0,
[](const tbb::blocked_range<double*> &r, double value) -> double {
return std::accumulate(r.begin(), r.end() value);
},
std::plus<double>()
);
Run Code Online (Sandbox Code Playgroud)
我的(野生)的猜测是,pdTempCurr[sCartesianSize-1]大约0.0003将占经历的数值差异.