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

时间:2017-11-17 16:20:22

标签: 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. 使用块安排
  3. 这两种方式要求我知道处理器缓存大小有多大。假设我想在未知系统上运行我的程序(我不知道缓存大小有多大)。这段代码是否有任何变通方法,我不需要知道缓存大小?或者可能是一个C代码,可以读取程序运行的系统的缓存大小?

1 个答案:

答案 0 :(得分:1)

首先,虚假共享是一个性能问题 - 而不是正确性问题。对于所有数据访问,您无需不惜一切代价避免它 - 但是您应该在大多数数据访问时避免使用它。

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

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

您应该小心使用以下模式:

data[omp_get_thread_num()] = ...;

这很容易被错误分享。你应该避免全局分配相邻存储小的每线程数据的数据。