【发布时间】:2021-10-31 01:34:04
【问题描述】:
我是多线程新手,在尝试并行化一些 for 循环时发现了以下问题,我在其中操作 3D 数组。
当我只使用一个线程运行代码时,我得到了我期望的E_total 的值。但是,当我将相同的代码与 多线程 和 OpenMP 一起使用时,我通过以下方式设置 #pragma omp parallel for
// DO FIRST COMPUTATION STEP ON 3D ARRAY
#pragma omp parallel for
for (size_t ix = 0; ix < N; ix++) {
for (size_t iy = 0; iy < N; iy++) {
for (size_t iz = 0; iz < N; iz++) {
A1[ix][iy][iz] = ...;
}
}
}
// DO SECOND COMPUTATION --AFTER-- FIRST COMPUTATION
#pragma omp parallel for
for (size_t ix = 0; ix < N; ix++) {
for (size_t iy = 0; iy < N; iy++) {
for (size_t iz = 0; iz < N; iz++) {
A2[ix][iy][iz] = ...;
E_pot += something * A1[ix][iy][iz];
E_int += something * A2[ix][iy][iz];
}
}
}
E_total += (E_pot + E_int); // This result changes when 'omp parallel for' is used
我发现对于E_total,我得到了不同的结果。
由于循环操作是附加的或特定于网格点的(独立于不同的ijk),因此它们不应依赖于循环内的任何顺序。
是否有可能在所有先前的第一个循环操作完成之前启动第二个 for 循环?如果是这样,我该如何防止这种情况发生,或者我需要注意哪些其他错误?
对不起,如果这是一个非常基本的问题,但我在网上找不到相关问题。提前致谢!
【问题讨论】:
-
我认为您在
E_pot和E_int两个变量上存在竞争条件。请在第二个parallel for构造中添加reduction(+:E_pot)和reduction(+:E_int)。 -
非常感谢,效果很好!您想重新发布您的评论作为答案,以便我接受它作为解决方案吗?
标签: c++ multithreading loops parallel-processing openmp