我正在用C中的OpenMP来并行化程序。我的程序中有一节将计算的值插入到数组中。代码将如下所示:


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


根据我的了解,我认为这段代码将在数组arr处发生False Sharing问题。为了避免此问题,我找到了几种方法,例如:


数组填充
大块调度


这两种方式要求我知道处理器高速缓存的大小。假设我想在未知系统上运行程序(我不知道缓存大小有多大)。此代码是否有不需要我知道缓存大小的变通办法?还是可以读取程序正在运行的系统的缓存大小的C代码?

最佳答案

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

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

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

您应该注意以下模式:

data[omp_get_thread_num()] = ...;


这很容易出现错误共享。您应该避免全局分配数据,在这些数据中小线程数据相邻存储。

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

10-12 05:55