OpenMP并行化结构体数组函数无性能提升问题排查与解决
N体引力模拟OpenMP并行化无性能提升问题排查与解决
问题背景
正在开发一款N体引力模拟代码,单核心的积分器与力计算逻辑已实现,尝试用OpenMP进行多线程并行化,但对OpenMP及共享内存技术细节不熟悉。
核心代码实现
使用的state结构体定义:
typedef struct state { int num_particles; particle* particles; octree *ot; params sim_cfg; } state;
并行化的直接法力计算代码:
void direct(state *sim) { #pragma omp parallel for for(int i = 0; i < sim->num_particles; i++) { sim->particles[i].acc = (vec3){0,0,0}; direct_acc(&sim->particles[i], *sim); } } void direct_acc(particle *p, state sim) { for(int j = 0; j < sim.num_particles; j++) { if(p == sim.particles+j) continue; p->acc = vec_add(p->acc, vec_scale(fg_calc(*p, sim.particles[j], sim.sim_cfg), 1/p->mass)); } }
性能异常表现
模拟结果符合预期,但不同线程数下无性能提升,甚至有小幅下降:
控制台time命令测试结果
1 thread real 0m0.816s user 0m0.815s sys 0m0.001s
2 threads real 0m0.826s user 0m0.825s sys 0m0.000s
4 threads real 0m0.855s user 0m0.854s sys 0m0.000s
使用OpenMP标准计时函数测试结果
1 thread Elapsed time 0.822067s
2 threads Elapsed time 0.870764s
4 threads Elapsed time 0.823142s
已确认编译时添加了-fopenmp参数,且能正常运行其他OpenMP示例程序,初步判断代码无线程冲突,但无法定位问题。
问题解决与验证
问题根源
编译配置错误:Makefile中仅给目标文件添加了-fopenmp标志,导致无论调用多少次omp_set_num_threads(),omp_get_num_threads()始终返回1,实际未启用多线程。
修复后性能测试(1000个质点,1000个时间步)
1 thread Elapsed time 13.406991s
2 threads Elapsed time 6.908134s
4 threads Elapsed time 4.112684s
8 threads Elapsed time 3.058720s
12 threads Elapsed time 2.328875s
内容的提问来源于stack exchange,提问作者CodeKraken
相关产品推荐
相关产品推荐

