c - OpenMP 实现还原

标签 c openmp

我需要实现缩减操作(对于每个线程,值应该存储在不同的数组条目中)。但是,对于更多线程,它运行得更慢。有什么建议吗?

double local_sum[16];.
//Initializations....
#pragma omp parallel for shared(h,n,a) private(x, thread_id) 
for (i = 1; i < n; i++) {
    thread_id = omp_get_thread_num();
    x = a  + i* h;
    local_sum[thread_id] += f(x);
}

最佳答案

您正在经历虚假分享的影响。在 x86 上,单个缓存行的长度为 64 字节,因此包含 64/sizeof(double) = 8 个数组元素。当一个线程更新其元素时,它运行的核心使用缓存一致性协议(protocol)使所有其他核心中的同一缓存行无效。当另一个线程更新它的元素,而不是直接在缓存上操作时,它的核心必须从上层数据缓存或主内存重新加载缓存行。这会显着降低程序执行速度。

最简单的解决方案是插入填充,从而将不同线程访问的数组元素分散到不同的缓存行中。在 x86 上,这将是 7 个 double 元素。因此,您的代码应如下所示:

double local_sum[8*16];
//Initializations....
#pragma omp parallel for shared(h,n,a) private(x, thread_id) 
for (i = 1; i < n; i++) {
    thread_id = omp_get_thread_num();
    x = a  + i* h;
    local_sum[8*thread_id] += f(x);

不要忘记在末尾对数组求和时只取第 8 个元素(或将所有数组元素初始化为零)。

关于c - OpenMP 实现还原,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21445901/

相关文章:

c - 我怎么能再次 "turn on"标准输出?

c - 进程返回 -1073741819 (0xC0000005)

caching - 显式 openmp 刷新是否会导致缓存行刷新?

c++ - 用两条语句并行化 while 循环(Floyd 循环检测算法)

c - OpenMP 并行化效率不高

c - I2C接收、PIC中错误数据接收

c - 如果比较两个指针的地址而不是内容,gcc/g++ 警告?

c - Erlang NIF 数字返回类型

OpenMP 并行用于模运算

c - OpenMP 递增计数并将值分配给数组