parallel_reduce 双重返回不正确的结果
parallel_reduce on double returning incorrect result
我正在尝试使用 Intel 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];
此代码returns正确值为“317.277493”;但是这个 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>()
);
坚持认为结果是“317.277193”。
我在这里错过了什么?
虽然所有关于求和顺序的评论都是完全正确的,但这里的简单事实是您的代码中存在错误。在定义范围时,所有 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>()
);
我的(大胆的)猜测是 pdTempCurr[sCartesianSize-1]
大约在 0.0003
附近,这将解释所经历的数字差异。
我正在尝试使用 Intel 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];
此代码returns正确值为“317.277493”;但是这个 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>()
);
坚持认为结果是“317.277193”。
我在这里错过了什么?
虽然所有关于求和顺序的评论都是完全正确的,但这里的简单事实是您的代码中存在错误。在定义范围时,所有 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>()
);
我的(大胆的)猜测是 pdTempCurr[sCartesianSize-1]
大约在 0.0003
附近,这将解释所经历的数字差异。