0

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

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

从我了解到的情况来看,我认为这段代码会在数组中出现 False Sharing 问题arr。为了避免这个问题,我找到了几种方法,例如:

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

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

4

1 回答 1

2

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

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

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

您应该小心以下模式:

data[omp_get_thread_num()] = ...;

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

于 2017-11-18T09:55:51.457 回答