并行返回错误结果的parallel_reduce

时间:2015-11-07 19:14:50

标签: c++ parallel-processing openmp tbb

我正在尝试使用英特尔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];

此代码返回正确的值“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>()
                                        );

坚持认为结果为“317.277 193 ”。

我在这里缺少什么?

1 个答案:

答案 0 :(得分:5)

虽然关于汇总顺序的所有评论都是完全正确的,但这里的简单事实是你的代码中有一个错误。所有freshest_replystd::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]左右,这将解释所经历的数值差异。