c - OpenMP - 没有错误共享的数组插入

标签 c caching parallel-processing openmp false-sharing

我正在使用 C 语言的 OpenMP 来并行化我的程序。我的程序中有一个部分将计算值插入到数组中。代码将是这样的:

#pragma omp parallel for
for(i=0; i<bignumber; i++) {
    arr[i] = mycalc(i);
}

根据我了解到的情况,我认为这段代码会在数组arr处出现错误共享问题。我发现有几种方法可以避免这个问题,例如:

  1. 数组填充
  2. 分块调度

这两种方法要求我知道我的处理器缓存大小有多大。假设我想在一个未知的系统上运行我的程序(我不知道缓存大小有多大)。此代码是否有任何不需要我知道缓存大小的解决方法?或者也许是可以读取程序运行所在系统的缓存大小的 C 代码?

最佳答案

首先,错误共享是性能问题,而不是正确性问题。您不必在所有数据访问中不惜一切代价避免它 - 但您应该在大多数数据访问中避免它。

您的简单循环模式没有问题。您可以坚持使用实现的默认值。如果需要,您可以使用 schedule(static) - 除非您指定 block 大小,否则 OpenMP 只会为每个线程分配一个大块。这意味着每个线程最多有两个受错误共享影响的缓存行(边界)。从统计数据来看,这并不重要。

从最大可能的 block 大小开始是一个很好的默认值。仅当您出于其他原因减少 block 大小时,例如负载平衡,您必须小心不要获得太多错误共享。将 block 大小保持为 2 的幂的倍数通常是一个好主意。

您应该小心以下模式:

data[omp_get_thread_num()] = ...;

这很容易出现虚假共享。您应该避免在相邻存储小型每线程数据的情况下全局分配数据。

关于c - OpenMP - 没有错误共享的数组插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47355024/

相关文章:

java - 更改 JAVA DNS 缓存设置

java - 避免死锁示例

c - 使用 fscanf 和 sscanf 从文件读取格式化输入

c - 如何将一个文件中每一行的特定数量的字符复制到另一个文件

c - 了解malloc的不同方法

c - 仅使用循环来区分两个字符串

c - 在 Linux 中实用地检测缓存未命中和命中

c# - 如何阻止浏览器(尤其是Internet Explorer)进行JavaScript的 super 缓存?

c++ - 令人尴尬的并行代码的低性能

java - 在 Java 7 中实现并发和并行