并行计算MPI简介
本文最后更新于 2018-11-19【2355 天前】,文中所描述的信息可能已发生改变,请谨慎使用。如有问题或建议,欢迎在文章底部留言参与讨论!
消息传递界面/接口(英语:Message Passing Interface,缩写MPI)是一个并行计算的应用程序接口(API),常在超级计算机、计算簇等非共享内存环境程序设计。
MPI 是一种接口,常用的实现方式是开源的 OPENMPI 和 Intel 商业化的 IMPI。
单节点/本地
正常的单机使用 mpi,一般不会出现什么问题,直接使用 mpirun -np 并行数 命令
即可,以下是完整的一个 C 语言例子。
首先编写源码,如 mpi-hello.c
#include <mpi.h>
#include <stdio.h>
int main(int argc, char** argv) {
// 初始化 MPI 环境
MPI_Init(NULL, NULL);
// 通过调用以下方法来得到所有可以工作的进程数量
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
// 得到当前进程的秩
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
// 得到当前进程的名字
char processor_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
MPI_Get_processor_name(processor_name, &name_len);
// 打印一条带有当前进程名字,秩以及
// 整个 communicator 的大小的 hello world 消息。
printf("Hello world from processor %s, rank %d out of %d processors\n",
processor_name, world_rank, world_size);
// 释放 MPI 的一些资源
MPI_Finalize();
}
然后使用mpicc
进行编译,如果是Fortran,使用对应的mpif90
或者mpifort
。
mpicc mpi-hello.cpp -o mpi-hello.x
最后使用对应版本的mpirun执行,
$ mpirun -np 5 ./mpi-hello.x
Hello world from processor login1, rank 1 out of 5 processors
Hello world from processor login1, rank 2 out of 5 processors
Hello world from processor login1, rank 3 out of 5 processors
Hello world from processor login1, rank 4 out of 5 processors
Hello world from processor login1, rank 0 out of 5 processors
多节点/集群使用
对于单节点/本地使用,一般不会出错,但很多时候都是在集群上进行的,可能会使用诸如 Torque PBS等任务管理系统,由
系统进行管理和分配计算,这时应当注意,源码撰写和编译和单机使用没有什么不同,但用 mpirun 执行任务时会略有不同。
原因在于,这时候,你的计算任务不是在本地执行的,可能需要使用集群上的几十甚至更多个核,会使用多个节点,就需要
告诉它,应该在哪些节点上进行计算。
那如何告诉 mpi 在哪些节点上执行任务呢?实现的方式很简单,通过加参数来实现。
mpirun -hostfile NODEFILE -np 40 ./mpi-hello.x
其中,NODEFILE
是一个文本文件,其中每一行代表一个节点名称。
对于使用PBS系统的来说,NODEFILE该如何设定呢?这里,PBS系统会告诉我们,我们这个任务得到了哪些节点,并把这个节点文件的路径保存为
变量PBS_NODEFILE
,所以只需要把上面的NODEFILE
替换为 $PBS_NODEFILE
即可。
一个PBS脚本的例子:
#!/bin/bash -x
#PBS -l nodes=2:ppn=20 ##使用两个节点,每个节点有20个核
#PBS -j oe
#PBS -q test ## 任务提交在test队列上
#PBS -N try ## 任务名称
#PBS -r y
CMD='/home/test/cluster-test'
#define MPI PATH
MPIRUN=/usr/mpi/openmpi/bin/mpirun
#Setup the OpenMPI topology
n_proc=$(cat $PBS_NODEFILE | wc -l)
cd $PBS_O_WORKDIR
$MPIRUN --mca btl openib,self,sm -hostfile $PBS_NODEFILE -np $n_proc $CMD >log.out 2>&1
exit 0
或许有人会问,如果不加这个hostfile参数会发生什么情况呢?一个可能的情况是,在只有20个核的节点上执行40个mpi进程。一般情况下,这些任务计算密集型的,同时还会伴随着大量的网络通讯,一个后果就是计算进行的很慢,更严重的后果是导致进程间的通讯网络长时间超负载,进而导致宕机,很不幸,我就遇到了这种情况,只是不清楚集群的宕机是否跟这个有直接联系。
参考
本文作者:Quanyin Tang
本文链接:并行计算MPI简介 - https://www.imtqy.com/mpi-intro.html
版权声明:如无特别声明,本文即为原创文章,仅代表个人观点,版权归 Quanyin 所有,未经允许禁止转载,经授权转载请注明出处!
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。