在向量上声明缩减,在 1 个线程上运行给出的结果与没有 openmp 的结果不同
Declare Reduction over Vector, Running on 1 thread gives different result than without openmp
我有以下一段代码,即使我在 1 个线程上运行它,它也给出了错误的答案。如果注释掉 for 循环之前的两个杂注,则代码将给出正确的结果。这怎么可能?我认为在 1 个线程上,使用 OpenMP 和不使用 OpenMP 之间没有区别,除了可能有一些小开销。另外,我应该怎么做才能获得"正确的行为"? 当我只有一个 for 循环时,我没有同样的问题,但是超过 1 个,它不像我想象的那样工作。
#include<iostream>
#include<vector>
#include<algorithm>
#include<omp.h>
using namespace std;
#pragma omp declare reduction(vec_double_plus : std::vector<double> :
std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<double>()))
initializer(omp_priv = omp_orig)
int main() {
vector<int> v;
vector<double> w(2);
for (int i = 0; i < 1000; i++) {
if (i % 2 == 0) {
v.push_back(0);
}
else {
v.push_back(1);
}
}
#pragma omp parallel for reduction(vec_double_plus:w)
for (int i = 0; i < 500; i++) {
int r = v[i];
w[r] += i;
}
#pragma omp parallel for reduction(vec_double_plus:w)
for (int i = 500; i < 1000; i++) {
int r = v[i];
w[r] += i;
}
std::cout << w[0] << std::endl;
std::cout << w[1] << std::endl;
}
问题是,代码假设来自外部范围的原始变量是使用归约的中性元素初始化的 - 即w
充满了零。它将从外部创建本地副本,并将其再次添加到原始副本中。这甚至发生在单个线程上。
您可以更改代码以使用零初始化omp_priv
,如下所示:
initializer(omp_priv = decltype(omp_orig)(omp_orig.size()))
代码对我来说看起来很熟悉,很抱歉造成混乱。我会修复原始答案。
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- valgrind-hellgrind与泄漏检查的结果不同
- OpenMP阵列性能较差
- 用C++20 fmt限制结果的总大小
- 如何返回一个类的两个对象相加的结果
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- OpenMP卸载说'fatal error: could not find accel/nvptx-none/mkoffload'
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- Openmp结果不稳健
- 为什么这段代码(在 Matlab 的 MEX 文件中使用 OpenMP)给出不同的结果?
- C++ openmp 并行计算计算错误的结果
- 在向量上声明缩减,在 1 个线程上运行给出的结果与没有 openmp 的结果不同
- OpenMP循环结果为零
- 在与 OpenMP 并行的嵌套 for 循环中写入共享数组(通过指针)如何产生错误的结果
- OpenMP崩溃会产生错误的结果
- 在 OpenMP 中加入数组结果
- 作为OpenMP杂注结果的中间代码
- MxCalloc和MxFree与OpenMP结果双重免费或损坏
- 如何广播OpenMP单块的结果