【问题标题】:parallel_reduce on double returning incorrect result双重返回不正确结果的parallel_reduce
【发布时间】:2015-11-07 19:14:50
【问题描述】:

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

此代码返回正确的值,即“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”。

我在这里错过了什么?

【问题讨论】:

  • 1e-4 对于很多领域来说都相当不错。 tbb 和 omp 可能利用不同的优化。
  • 添加的顺序根据并行度的不同而不同。在数学中,加法是关联和交换的,但在浮点中不是这样。因此,您必须期望总和会根据加法的顺序而变化。顺便说一句,为什么您认为第一个答案更“正确”?
  • 显然我对精确度不满意,并询问 I 是否遗漏了任何东西。 @BrianCain
  • 没有任何并行性,结果就是 OpenMP 当前给出的结果。 @JSF
  • 考虑使用任意精度算术作为参考。另请参阅phys.uconn.edu/~rozman/Courses/P2200_11F/downloads/…,了解有关补偿总和的讨论。

标签: c++ parallel-processing openmp tbb


【解决方案1】:

虽然所有关于求和顺序的 cmets 都是完全正确的,但这里的简单事实是您的代码中有一个错误。在定义范围时,所有std::thrust::tbb:: 算法或构造函数都遵循相同的理念,即指示从第一个要采用的元素到第一个不采用的元素,如for ( auto it = v.begin(); it &lt; 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 附近,这将解释所经历的数字差异。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-14
    • 2012-04-11
    • 2016-02-06
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-01
    相关资源
    最近更新 更多