关键约束
不能使用 OpenMP,所有加速必须来自 MPI
与 HW2-1 相同的粒子模拟,但现在使用 MPI 分布式内存并行。每个进程只持有部分粒子,跨进程相互作用通过消息传递完成。
关键约束
不能使用 OpenMP,所有加速必须来自 MPI
规模限制
最多 2 节点、128 核、6,000,000 粒子
可修改文件
只能修改 mpi.cpp 中的 simulate_one_step 和 gather_for_save
评分重点
扩展性(Strong/Weak Scaling)+ 性能 + 方法论解释
| 文件 / 函数 | 角色 | 可以修改? | 课程关联 |
|---|---|---|---|
| mpi.cpp → simulate_one_step | 单步 MPI 并行模拟:力计算 + 粒子迁移 | ✅ 是 | Lec 7, 8 |
| mpi.cpp → gather_for_save | 收集所有粒子位置用于输出 | ✅ 是 | Lec 8 |
| common.h / common.cpp | 数据结构、I/O、验证 | ❌ 否 | — |
| serial.cpp / openmp.cpp | 串行/OpenMP 参考实现 | ❌ 否 | HW2.1 |
将模拟空间划分为 p 个子域,每个进程负责一个子域内的粒子。
每个子域边界外扩 cutoff 距离,存储相邻进程的粒子副本(ghost particles)。
MPI_Sendrecv 或 MPI_Isend/Irecv粒子移动后可能离开当前子域,需要迁移到正确的进程。
MPI_Alltoallv 进行不规则数据交换每个进程独立计算本地粒子与本地 + ghost 粒子的相互作用。
输出时需要把所有粒子收集到根进程。
MPI_Gather 或 MPI_Gatherv(粒子数不均)| 原语 | 用途 | 类型 |
|---|---|---|
| MPI_Send / MPI_Recv | 点对点阻塞通信 | 点对点 |
| MPI_Sendrecv | 同时发送和接收,避免死锁 | 点对点 |
| MPI_Isend / MPI_Irecv | 非阻塞通信,可重叠计算 | 点对点 |
| MPI_Allgather | 全收集:每个进程获得所有数据 | 集合 |
| MPI_Alltoallv | 全交换:不规则数据分布 | 集合 |
| MPI_Barrier | 全局同步 | 集合 |
| 扩展性类型 | 定义 | 关注指标 |
|---|---|---|
| Strong Scaling | 固定问题规模,增加处理器数 | S = T₁ / Tₚ,理想 = p |
| Weak Scaling | 固定每处理器问题规模,增加处理器数 | E = T₁ / Tₚ,理想 = 1 |
| 通信开销 | T_comm / T_total 随 p 的变化 | 应尽可能小 |
| 负载均衡 | 最大 / 平均负载比 | 理想 = 1 |
MPI_Send / MPI_Recv 顺序不当会导致死锁。优先使用 MPI_Sendrecv 或非阻塞通信。
MPI_Allgather 会让通信量 O(p) 增长。只在必要时收集数据。
Q1. Ghost Layer (Halo) 的厚度应该如何选择?
Q2. 粒子迁移时,应该使用哪个 MPI 原语?
Q3. 在 3D 空间模拟中,哪种域分解的通信量最小?
Q4. 在 HW2.2 中,能否使用 OpenMP 加速单个 MPI 进程的计算?
Q5. 关于 Strong Scaling 和 Weak Scaling,以下哪项正确?