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