MPI程序叠加OpenMP后并行区域性能严重下降的问题求助
MPI程序叠加OpenMP后并行区域性能严重下降的问题求助
我用C语言写了一个粒子模拟程序,用4个MPI进程运行,相比串行版本速度已经快很多了。但其中有一段N²复杂度的代码,需要把当前进程里的每个粒子和同进程的其他粒子,以及从其他进程共享过来的“边界粒子”做对比。我本来打算用#pragma omp parallel for并行化外层循环来提速,但试了各种OpenMP指令组合后,模拟反而变得巨慢——核心问题就是这段嵌套循环的耗时暴增。
我试过在并行区域里加schedule和reduction,但没什么效果;也试过用8线程或者4线程,同样没用;还测试了不同的系统规模(想看看是不是开销大到超过收益,但显然不是),也调过编译器优化选项,都没用。
计时结果显示,四个MPI进程里有一个在这段代码上耗时特别久,导致整个模拟必须等它完成才能进入下一个时间步,拖慢了整体速度。按理说任务分配得挺均匀的,不该出现这种情况。
代码片段(核心逻辑保留,部分细节做了伪代码处理)
double calc_1 = omp_get_wtime(); #pragma omp parallel for num_threads(4) private(distances, particle_one) for (int p = 0; p < myNumParticles; p = p + 2){ //Particle* particle_iter = &particles[0]; // printf("p%d: I am thread %d\n", my_rank, omp_get_thread_num()); // fflush(stdout); double force_x = 0; double force_y = 0; particle_one[0] = positions[p]; particle_one[1] = positions[p+1]; //#pragma omp parallel shared(force_x, force_y) // { if (particle_one real){ // for (int i = 0; i < (myNumParticles-8); i = i + 8){ //#pragma omp parallel for private(distances) for (int i = 0; i < myNumParticles; i += 2){ if (i != p){ // lj_counter2++; particle_two[0] = positions[i]; particle_two[1] = positions[i+1]; if (particle within distance cutoff){ force_function(); // modifies forces array force_x += (forces[0]); force_y += (forces[1]); } distances[0] = 0; distances[1] = 0; } } // repeat conparison against border particles for (int j = 0; j < (num_particles_local); j += 2){ particle_three[0] = myBorderParticles[j]; particle_three[1] = myBorderParticles[j+1]; if (particle is real){ if (within distance cutoff) { force_function(); // modifies forces array force_x += (forces[0]); force_y += (forces[1]); } distances[0] = 0; distances[1] = 0; } else { // if particle with position {0, 0} found, you're at the end break; } } } accelerations[p] = force_x; accelerations[p+1] = force_y; } double calc_2 = omp_get_wtime(); calc_time += (calc_2-calc_1);
3600个粒子系统的计时结果
- 仅MPI版本:
总耗时373.6秒,其中上述嵌套循环耗时在332.47-349.08秒之间 - MPI+OpenMP版本:
总耗时1606.2秒,其中上述嵌套循环耗时在583.09-1579.96秒之间(不同进程耗时差异极大)
更小规模系统的计时对比
| 粒子数量 | 仅MPI耗时(秒) | MPI+OpenMP耗时(秒) |
|---|---|---|
| 225 | 27 | 30 |
| 400 | 37 | 33 |
| 625 | 60 | 101 |
| 900 | 99 | 293 |
| 1225 | 153 | 490 |
| 1600 | 239 | 735 |
我的运行环境是4个节点,每个节点有28+核心,内存需求也在合理范围内。用Slurm提交任务,启动命令是mpiexec -n 4 ./executable num_particles box_size > slurms/output.txt。
备注:内容来源于stack exchange,提问作者Luna Morrow
相关产品推荐
相关产品推荐

