mpirun的运行原理 (来自deepseek)
我们来深入浅出地讲解 mpirun(以及其同义词如 mpiexec, orterun)的运行原理。
mpirun 是 MPI(消息传递接口)实现(如 Open MPI, MPICH, Intel MPI)提供的一个命令行工具,它的核心任务非常简单:启动一个并行作业,并在指定的多个计算节点上创建和管理多个进程,让这些进程能够通过 MPI 库进行通信。
它的运行原理可以分解为以下几个关键阶段和组件:
核心思想:一个“管理器-工作者”模型
可以把 mpirun 进程本身看作一个 “管理器” ,而它启动的 MPI 进程则是 “工作者”。
1. 解析命令行参数和主机信息
当你执行类似下面的命令时:
bash
mpirun -n 4 -host node1,node2,node3,node4 ./my_mpi_program
mpirun 首先会:
-
解析参数:知道要启动 4 个进程 (
-n 4)。 -
构建主机列表:知道要在
node1,node2,node3,node4这四个节点上运行。 -
定位程序:找到可执行文件
./my_mpi_program。
2. 启动基础运行环境
这是最关键的一步。mpirun 本身是 MPI 实现中一个叫做 ORTE (Open Run-Time Environment) 或 PMI (Process Management Interface) 的前端。
-
ORTE: 是 Open MPI 使用的运行时环境。
-
PMI: 是 MPICH 及其衍生版本(如 Intel MPI)使用的进程管理接口。
这个运行时环境负责所有底层的进程管理、通信和资源管理的脏活累活。
具体启动流程如下:
-
启动“头节点”上的守护进程:
-
mpirun首先会在你运行命令的那个节点(头节点) 上启动一个高级别的管理器进程,通常称为orted(ORTE 守护进程)或hydra_pmi_proxy(对于 MPICH-Hydra)。 -
这个
orted是全局的“总指挥”。
-
-
在远程节点上启动守护进程:
-
然后,总指挥
orted会通过某种远程启动机制(如 SSH、RSH 或专门的资源管理器如 Slurm/PBS 提供的接口)连接到主机列表中的其他节点(node2,node3,node4)。 -
在每个远程节点上,它都会启动一个对应的
orted守护进程。这些远程的orted是“分指挥”。
-
-
形成通信网络:
-
现在,所有节点上的
orted守护进程会相互建立连接,形成一个内部的管理网络。这个网络独立于 MPI 进程间用于数据传输的数据网络(如 InfiniBand, Ethernet)。
-
3. 启动 MPI 进程
管理网络建立好后,真正的 MPI 进程启动开始了:
-
总指挥分发任务:头节点的
mpirun通过管理网络向所有orted(包括本地的和远程的)发送命令:“在你的节点上,启动 N 个my_mpi_program进程”。 -
分指挥执行:每个节点上的
orted守护进程接收到命令后,fork()并exec()出指定数量的 MPI 进程。 -
设置环境:在启动每个 MPI 进程时,
orted会为其设置关键的环境变量,最重要的是:-
PMI_FD: 一个文件描述符,用于与orted通信。 -
或者其他类似的通信通道标识符。
-
4. 信息交换与建立通信域
这是 MPI 魔法发生的地方。每个 MPI 进程启动后,它需要知道:
-
“我是谁?”(我的进程编号
MPI_Rank) -
“总共有多少人?”(通信域大小
MPI_Comm_size) -
“如何联系到其他人?”(其他进程的地址信息)
这个过程是通过 PMI(Process Management Interface) 或 PRRTE(PMIx Reference RunTime Environment) 来完成的。
-
MPI 进程联系本地守护进程:每个 MPI 进程启动后,会通过
PMI_FD这个“管道”与本节点的orted守护进程进行通信。这是一个本地通信,非常高效。 -
信息收集:MPI 进程向
orted注册自己,并询问初始化信息。 -
信息交换:所有节点上的
orted通过它们之间的管理网络,交换所有 MPI 进程的联系信息(例如:IP地址、端口号、用于高速网络的硬件地址等)。 -
信息分发:一旦
orted收集齐了所有信息,它就会通过PMI_FD将完整的“通讯录”(包含所有进程的地址和排名)分发给它管理的每一个 MPI 进程。 -
建立连接:MPI 进程拿到“通讯录”后,彼此之间会建立 TCP 连接或利用 RDMA(远程直接内存访问)等技术建立高速网络连接,形成 MPI 的通信域(如
MPI_COMM_WORLD)。
5. 运行与监控
-
执行用户代码:此时,所有 MPI 进程开始执行
my_mpi_program中的main函数,并进行消息传递。 -
标准 I/O 管理:默认情况下,所有 MPI 进程的
stdout和stderr都会被重定向回mpirun,这就是为什么你能在同一个终端上看到所有进程的输出(虽然可能是乱序的)。你可以使用-output-filename等选项改变这一行为。 -
信号处理和监控:
mpirun和orted会监控 MPI 进程的状态。如果一个进程异常退出(例如 Segmentation Fault),管理器会终止所有其他进程。当你按下Ctrl+C时,信号也会被传播给所有 MPI 进程。
6. 终止与清理
-
当所有 MPI 进程正常退出后,它们会通知本地的
orted。 -
orted然后通知头节点的总指挥。 -
总指挥会命令所有
orted自行退出。 -
最后,
mpirun本身退出,返回一个适当的退出码。
总结与类比
| 组件 | 角色 | 类比 |
|---|---|---|
mpirun |
总司令 | 公司的CEO,制定总体战略(命令行参数)。 |
orted |
经理层 | 公司的中层经理(本地和远程)。他们听从CEO,管理基层员工。 |
| MPI 进程 | 工作者 | 公司的基层员工,负责具体工作(执行计算)。他们只和直属经理打交道。 |
| 管理网络 | 内部管理通道 | 经理之间的电话会议/内部邮件系统。 |
| 数据网络 | 工作协作通道 | 员工之间为了完成项目而进行的直接沟通和文件传输。 |
| PMI | 工作流程接口 | 员工向经理汇报工作和获取资源的标准化流程(如申请办公用品、获取同事联系方式)。 |
现代环境的补充:与作业调度器集成
在高性能计算集群中,你通常不会直接在所有节点上 SSH,而是通过作业调度器(如 Slurm, PBS/Torque)来提交作业。
在这种情况下,mpirun 的工作会大大简化:
-
你通过
sbatch(Slurm)提交一个作业脚本。 -
Slurm 的
srun负责在所有分配的计算节点上启动任务。 -
在作业脚本中调用
mpirun时,mpirun会自动检测到它正在 Slurm 环境中运行。 -
于是,
mpirun不再使用 SSH,而是直接调用 Slurm 的接口(例如通过 PMI-2)来启动和管理 MPI 进程。Slurm 自身扮演了“总指挥”和“分指挥”的角色。
所以,现代 mpirun 的原理是:作为一个灵活的包装器,根据当前环境(直接SSH、Slurm、PBS等)选择合适的底层启动机制(ORTE, PMI等),以高效地完成分布式进程的启动、初始化和管理工作。
更多推荐

所有评论(0)