【发布时间】: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