c++ - parallel_reduce on double 返回不正确的结果

标签 c++ parallel-processing openmp tbb

我正在尝试使用英特尔 TBB parallel_reduce 来获取由 double 组成的数组元素的总和。但是,与 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”。

我在这里错过了什么?

最佳答案

虽然所有关于求和顺序的评论都是完全正确的,但这里的简单事实是您的代码中存在错误。全部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附近这将解释所经历的数字差异。

关于c++ - parallel_reduce on double 返回不正确的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33586737/

相关文章:

c++ - 内存布局练习 C++

c++ - 处理 utf8 编码的 char* 数组

c++ - 不区分大小写的字符串::查找

Python Dask 并行运行 Bag 操作

c++ - OpenMP 多线程建议

c++ - 使用 C++、libpng 和 OpenMP 并行创建 PNG 文件

c++ - 指针初始化之间的区别

clojure - 如何并行减少 Clojure 序列

java - 使用多线程或优先队列确定特定 API 调用优先级的方法?

c# - 使用omp优化或提出c++,C#代码以查找所有相似的k个图案