gpt4 book ai didi

c - OpenMP 中的缩减操作在幕后是如何工作的?

转载 作者:太空宇宙 更新时间:2023-11-04 06:47:12 25 4
gpt4 key购买 nike

我正在尝试优化 parallel-for 循环中的性能,其中我有一个缩减变量(称为 delta)并且我是想知道 OpenMP 库是如何在后台处理它的。

让我们以下面的一段代码为例,我在循环的开始简单地将变量声明为一个缩减变量,如下所示:

#pragma omp parallel shared(delta, A, B, rows, colms) private(i, j)
.
.
.
#pragma omp for reduction(+:delta)
for (i=1; i<=rows; i++){
for (j=1; j<=colms; j++){
delta += fabs(A[i][j]- B[i][j]);
}
}
.
.
.
//end of parallel region

我想知道在计算期间是否每个线程在访问 delta 变量时都设置了一个锁,此外我是否可以通过用数组替换 delta 变量来提高性能 < em>delta[number_of_threads],其中每个线程在计算时会写入数组的不同位置,然后对并行区域之后的所有元素求和。

最佳答案

每个线程在其栈帧上都有自己的“delta”副本:

#pragma omp parallel shared(delta, A, B, rows, colms) private(i, j)
{
double local_delta; // one copy per thread

__omp_init_schedule(1, rows, &lb, &ub);
for (i=lb; i<=ub; i++) {
for (j=1; j<=colms; j++) {
local_delta += fabs(A[i][j]- B[i][j]);
}
}
__omp_reduce(&delta, local_delta); // accumulate thread's delta with shared var
__omp_barrier(); // do the barrier of the for construct
}

以上内容请当作伪代码。实际代码模式将取决于实现、内联和 OpenMP 实现可能执行的各种其他优化。如果您想了解一些有关工作原理的信息,请查看 [1] 和 [2]。

__omp_reduce() 的实现可以是基于树的实现,也可以是使用锁或原子指令的顺序实现。 OpenMP 实现通常相当聪明,可以为机器和/或正在使用的线程数选择正确的算法。

进行 delta[numthreads] 修改可能会使性能降低 100 倍以上,因为这是错误共享的典型示例,如线程的 delta[0]线程一的 0 和 delta[1] 将在同一个缓存行中,这会导致缓存和内存上的大量流量。更好的方法是引入 patting delta[numthreads * 8](假设 delta 是 8 个字节),这样每个线程都有自己的缓存行。但是,您仍然需要执行最终聚合,并且 OpenMP 实现可能仍然做得更好。

[1] https://www.dontknow.de/openmp-stuff/the-thing-from-another-world-or-how-do-openmp-compilers-work-part-1/

[2] https://www.dontknow.de/openmp-stuff/thunk-you-very-much-or-how-do-openmp-compilers-work-part-2/

关于c - OpenMP 中的缩减操作在幕后是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56359957/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com