c++ - OpenMP 中的并行编程

标签 c++ c multithreading parallel-processing openmp

我有以下一段代码。

for (i = 0; i < n; ++i) {
  ++cnt[offset[i]];
}

其中 offset 是一个大小为 n 的数组,包含 [0, m)cnt 范围内的值> 是大小为 m 的数组,初始化为 0。我使用 OpenMP 对其进行并行化,如下所示。

#pragma omp parallel for shared(cnt, offset) private(i)
for (i = 0; i < n; ++i) {
  ++cnt[offset[i]];
}

根据本post中的讨论,如果offset[i1] == offset[i2] for i1 != i2,上面的代码可能会导致错误的cnt。我该怎么做才能避免这种情况?

最佳答案

这段代码:

#pragma omp parallel for shared(cnt, offset) private(i)
for (i = 0; i < n; ++i) {
  ++cnt[offset[i]];
}

在更新数组 cnt 期间包含竞争条件,要解决它,您需要保证这些更新相互排斥。这可以通过(例如)#pragma omp atomic update 来实现但正如评论中已经指出的那样:

However, this resolves just correctness and may be terribly inefficient due to heavy cache contention and synchronization needs (including false sharing). The only solution then is to have each thread its private copy of cnt and reduce these copies at the end.

另一种解决方案是每个 线程拥有一个私有(private)数组,并在并行区域的末尾手动将所有这些数组缩减为一个。可以找到这种方法的示例 here .

幸运的是,有了 OpenMP 4.5您可以使用专用编译指示减少数组,即:

#pragma omp parallel for reduction(+:cnt)

你可以看看this example关于如何应用该功能。

值得一提的是,@Jérôme Richard 亲切指出,关于数组的缩减原子方法:

Note that this is fast only if the array is not huge (the atomic based solution could be faster in this specific case regarding the platform and if the values are not conflicting). So that is m << n. –

一如既往,分析是关键!;因此,您应该使用上述方法测试您的代码,以找出最有效的方法。

关于c++ - OpenMP 中的并行编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67210928/

相关文章:

c++ - 如何禁用有关 clang 中匿名结构的警告?

c++ - 我的复制构造函数失败..如何复制指向对象的指针

c - insmod:错误:无法插入模块 kprobe_example.ko:不允许操作

c - 使用一个函数作为另一个函数的参数时的“error: invalid use of void expression”

c++ - 无权访问模板模板参数

C++:使用函数重载和 char 到 int 之间的隐式转换,反之亦然

c - 使用 GCC 驱动程序时,什么使静态库成为 "incompatible"?

c - 基准测试、顺序 x 并行程序。亚线性加速?

java - sleep 线程唤醒后会发生什么?

c# - 当主线程终止时 SynchronizationContext 会发生什么?