gpt4 book ai didi

c - 如何避免嵌套循环中 openMP 的开销

转载 作者:太空狗 更新时间:2023-10-29 16:45:24 35 4
gpt4 key购买 nike

我有两个版本的代码产生相同的结果,我试图只并行化嵌套 for 循环的内部循环。我没有得到太多加速,但我没想到会是 1 对 1,因为我只是尝试并行化内部循环。

我的主要问题是为什么这两个版本有相似的运行时间?第二个版本不是只 fork 线程一次并且避免像第一个版本那样在 i 的每次迭代中启动新线程的开销吗?

第一个版本的代码在外循环的每次迭代中启动线程,如下所示:

for(i=0; i<2000000; i++){
sum = 0;
#pragma omp parallel for private(j) reduction(+:sum)
for(j=0; j<1000; j++){
sum += 1;
}
final += sum;
}
printf("final=%d\n",final/2000000);

有了这个输出和运行时间:

OMP_NUM_THREADS=1

final=1000
real 0m5.847s
user 0m5.628s
sys 0m0.212s

OMP_NUM_THREADS=4

final=1000
real 0m4.017s
user 0m15.612s
sys 0m0.336s

第二个版本的代码在外层循环之前启动线程一次(?)并像这样并行化内层循环:

#pragma omp parallel private(i,j)
for(i=0; i<2000000; i++){
sum = 0;
#pragma omp barrier
#pragma omp for reduction(+:sum)
for(j=0; j<1000; j++){
sum += 1;
}
#pragma omp single
final += sum;
}
printf("final=%d\n",final/2000000);

有了这个输出和运行时间:

OMP_NUM_THREADS=1

final=1000
real 0m5.476s
user 0m4.964s
sys 0m0.504s

OMP_NUM_THREADS=4

final=1000
real 0m4.347s
user 0m15.984s
sys 0m1.204s

为什么第二个版本没有比第一个版本快很多?它不是避免了在每次循环迭代时启动线程的开销,还是我做错了什么?

最佳答案

OpenMP 实现可以使用线程池来消除在遇到并行构造时启动线程的开销。 OMP_NUM_THREADS 线程池为第一个并行构造启动,构造完成后从属线程返回到池中。当遇到稍后的并行构造时,可以重新分配这些空闲线程。

例如参见 thread pooling in the Sun Studio OpenMP implementation 的解释.

关于c - 如何避免嵌套循环中 openMP 的开销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37648594/

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