关于 mpi
mpi 是面向 Agent 的 MPI 并行编程技能,涵盖进程间通信、混合并行、作业启动和调试,适合开发和运行 HPC 应用。
主要功能
- 01点对点与集合通信
- 02非阻塞通信及计算重叠
- 03子通信器与 MPI+OpenMP
- 04使用 mpirun 和调度器启动
- 05MPI-IO 与性能问题排查
适用场景
- 01跨节点并行化计算
- 02实现矩阵分解或 FFT
- 03组合 MPI 进程与 OpenMP 线程
- 04排查死锁并进行并行文件 I/O
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mohitmishra786/ low-level-dev-skills --skill mpi安装后在 Claude Code 中输入/mpi确认已加载。
详细介绍
MPI
用途
指导 Agent 进行 MPI(消息传递接口)编程:点对点和集合通信、非阻塞操作、子通信器、MPI + OpenMP 混合模式、使用 mpirun 启动进程、调试技术、MPI-IO 以及常见性能问题。
适用场景
- 在多个节点或插槽间进行并行化
- 实现分布式算法(矩阵分解、FFT)
- 将 MPI 进程并行与 OpenMP 线程并行相结合
- 使用 Slurm/PBS +
mpirun运行 HPC 作业 - 调试死锁和消息不匹配问题
- 使用 MPI-IO 进行并行文件 I/O
工作流
1. 最简 MPI 程序
#include <mpi.h>
#include <stdio.h>
int main(int argc, char **argv) {
MPI_Init(&argc, &argv);
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
printf("Hello from rank %d of %d\n", rank, size);
MPI_Finalize();
return 0;
}
mpicc -o hello hello.c
mpirun -np 4 ./hello
# or
mpiexec -n 4 ./hello
2. 点对点通信
if (rank == 0) {
int data = 42;
MPI_Send(&data, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
} else if (rank == 1) {
int recv;
MPI_Recv(&recv, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("rank 1 got %d\n", recv);
}
带标签的消息:为 MPI_Recv 匹配标签和源进程。
3. 集合通信
int local = rank + 1;
int global_sum;
MPI_Allreduce(&local, &global_sum, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
// Broadcast
if (rank == 0) data = 100;
MPI_Bcast(&data, 1, MPI_INT, 0, MPI_COMM_WORLD);
// Scatter/Gather
MPI_Scatter(sendbuf, sendcount, MPI_INT, recvbuf, recvcount, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Gather(sendbuf, sendcount, MPI_INT, recvbuf, recvcount, MPI_INT, 0, MPI_COMM_WORLD);
| 集合通信 | 用途 |
|---|---|
MPI_Bcast | 一对多广播 |
MPI_Scatter | 分发数据块 |
MPI_Gather | 收集数据块 |
MPI_Allreduce | 归约并广播结果 |
MPI_Barrier | 同步 |
MPI_Alltoall | 全互换 |
4. 非阻塞通信
MPI_Request req;
MPI_Isend(buf, count, MPI_INT, dest, tag, MPI_COMM_WORLD, &req);
// overlap computation here
do_local_work();
MPI_Wait(&req, MPI_STATUS_IGNORE);
// Multiple requests
MPI_Request reqs[2];
MPI_Irecv(buf0, n, MPI_INT, 0, 0, comm, &reqs[0]);
MPI_Irecv(buf1, n, MPI_INT, 1, 0, comm, &reqs[1]);
MPI_Waitall(2, reqs, MPI_STATUSES_IGNORE);
通过将通信与计算重叠来隐藏延迟。
5. 子通信器
int color = rank / 4; // groups of 4
MPI_Comm subcomm;
MPI_Comm_split(MPI_COMM_WORLD, color, rank, &subcomm);
int subrank, subsize;
MPI_Comm_rank(subcomm, &subrank);
MPI_Comm_size(subcomm, &subsize);
MPI_Comm_free(&subcomm);
6. MPI + OpenMP 混合模式
#pragma omp parallel
{
int tid = omp_get_thread_num();
// thread-local work on rank's data partition
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_Allreduce(...);
export OMP_NUM_THREADS=4
mpirun -np 8 --bind-to core ./hybrid_app
# 8 ranks × 4 threads = 32 cores
使用 --map-by ppr:2:socket 将各个 rank 绑定到插槽。
7. 使用 hostfile 启动
# hostfile:
# node0 slots=4
# node1 slots=4
mpirun -np 8 --hostfile hosts.txt ./app
# Slurm integration
srun -n 64 ./app
# or
mpirun -np $SLURM_NTASKS ./app
# Debug: tag output by rank
mpirun -np 4 --tag-output ./app
# Sequential debug (one rank at a time)
mpirun -np 4 -gdb ./app
8. MPI-IO
#include <mpi.h>
MPI_File fh;
MPI_File_open(MPI_COMM_WORLD, "output.dat",
MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
MPI_Offset offset = rank * chunk_size;
MPI_File_write_at(fh, offset, buf, count, MPI_DOUBLE, MPI_STATUS_IGNORE);
MPI_File_close(&fh);
使用集合 I/O 提升性能:
MPI_File_write_at_all(fh, offset, buf, count, MPI_DOUBLE, MPI_STATUS_IGNORE);
9. 性能问题
Common bottlenecks
├── Load imbalance → dynamic scheduling (OpenMP) or redistribute MPI chunks
├── Serialization at rank 0 → tree-based reduce, parallel I/O
├── Excessive sync → replace Barrier with point-to-point where possible
├── Small messages → aggregate; use MPI_Pack or larger blocks
└── Alltoall on large process counts → consider MPI neighborhood collectives
# MPI profiling
mpiP # lightweight profiler
# or IPM, TAU MPI wrappers
常见问题
| 症状 | 原因 | 解决方法 |
|---|---|---|
| 在 MPI_Recv 处挂起 | 标签或源进程不匹配 | 检查 Send/Recv 配对;调试时使用 MPI_ANY_TAG |
| 死锁 | 循环等待 | 调整通信顺序;使用非阻塞操作 |
| Allreduce 结果错误 | 数据类型或计数错误 | 确认使用 MPI_INT 还是 MPI_DOUBLE |
| 扩展性差 | rank 0 成为瓶颈 | 分散 I/O 和聚合操作 |
MPI_ERR_TRUNCATE | 接收缓冲区太小 | 确保发送和接收计数匹配 |
| 混合模式超额订阅 | 线程数 × rank 数过多 | OMP_NUM_THREADS = cores/ranks |
相关技能
skills/hpc/openmp— MPI rank 内的线程级并行skills/hpc/rdma-verbs— MPI 下的低延迟互连skills/allocators/numa-programming— 将 rank 绑定到 NUMA 节点skills/profilers/linux-perf— 分析 MPI rank 的热点skills/debuggers/gdb— 调试单个 MPI 进程skills/compilers/gcc— MPI 编译器封装器标志
评论
支持 Markdown