我在C中使用OpenMP来并行化我的程序。我的程序中有一个部分将计算值插入数组中。代码将是这样的:
#pragma omp parallel for
for(i=0; i<bignumber; i++) {
arr[i] = mycalc(i);
}
根据我所学到的,我认为此代码将在数组arr
处出现错误共享问题。我发现有几种方法可以避免这个问题,例如:
这两种方式要求我知道处理器缓存大小有多大。假设我想在未知系统上运行我的程序(我不知道缓存大小有多大)。这段代码是否有任何变通方法,我不需要知道缓存大小?或者可能是一个C代码,可以读取程序运行的系统的缓存大小?
答案 0 :(得分:1)
首先,虚假共享是一个性能问题 - 而不是正确性问题。对于所有数据访问,您无需不惜一切代价避免它 - 但是您应该在大多数数据访问时避免使用它。
您的简单循环模式没有问题。您可以坚持使用实现的默认设置。如果需要,可以使用schedule(static)
- 除非指定块大小,否则OpenMP将仅为每个线程分配一个大块。这意味着每个线程最多有两个受错误共享影响的缓存行(边框)。从统计上来说,这不重要。
从最大可能的块大小开始是一个很好的默认值。只有当你因其他原因减少块大小时,例如负载平衡,你必须小心,不要太多的错误共享。将块大小保持为2的幂的倍数通常是个好主意。
您应该小心使用以下模式:
data[omp_get_thread_num()] = ...;
这很容易被错误分享。你应该避免全局分配相邻存储小的每线程数据的数据。