关于MPI和OpenMP不再赘述,可参考三个问题,关注两个人(李沐杨军):

1.算法研发工作中对于MPI和Spark的一些困惑?

2.从并行计算的角度,MPI 与 OpenMP 的对比?

3.MPI 在大规模机器学习领域的前景如何?

吐槽一句:不要再说MPI的容错能力渣了,MPI的标准设计是将容错交给应用程序了!!(你可以自己写容错,例如,xgboost的底层通信框架rabit


一.集群配置

总体配置 管理节点 计算节点

二.集群运维

总核数 = 物理CPU个数 X 每颗物理CPU的核数

总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数

# 查看物理CPU个数
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l

# 查看每个物理CPU中core的个数(即核数)
cat /proc/cpuinfo| grep "cpu cores"| uniq

# 查看逻辑CPU的个数
cat /proc/cpuinfo| grep "processor"| wc -l

#查看CPU信息(型号)
cat /proc/cpuinfo | grep name

#查看操作系统
cat /proc/version
三.MPI和集群

在二中了解到集群的基本信息之后,建立的通信结构如下图所示:

MPI&cluster

一个管理节点master和四个计算节点compute-x,每个计算节点8个core,由于超线程的存在,每个core支持两个超线程,并且每个计算节点有2个CPU,故一个计算节点的逻辑CPU是32。MPI负责管理节点和计算节点之间的通信,具体任务是数据分发和结果汇总。每个计算节点具体负责乘法计算,如下图:

matrix&multiplication

假设要利用4个计算节点参与计算(可通过PBS作业调度系统完成),则master负责矩阵A切分,并记录切分后的数据的起始地址和偏移量,然后将切分的某一块数据和矩阵B分发给对应的计算节点。例如,图中红色方框标准的内容,计算节点3计算矩阵A切分的第3块数据和矩阵B相乘的结果,虚线表示矩阵B的复制。

四.PBS作业调度系统

给出实践中用到的PBS脚本(zhp_mpi_mm.pbs):

#PBS -N zhp_mpi_mm
#PBS -o /home/zhpmatrix/code/c++/mpi/zhp_mpi_mm.out
#PBS -e /home/zhpmatrix/code/c++/mpi/zhp_mpi_mm.err
#PBS -l nodes=3:ppn=8
cd $PBS_O_WORKDIR
mpirun -np 24 -machinefile $PBS_NODEFILE ./mpi_mm

在具体运行的时候,将代码(mpi_mm.c)和PBS脚本(zhp_mpi_mm.pbs)放置管理节点上,提交任务:

qsub zhp_mpi_mm.pbs

运行结束,查看程序运行结果:

#正确运行
less /home/zhpmatrix/code/c++/mpi/zhp_mpi_mm.out

#错误运行
less /home/zhpmatrix/code/c++/mpi/zhp_mpi_mm.err
五.加速比和效率

在PBS脚本中设置的是使用3个计算节点,每个计算节点8个core。在性能测试阶段,将计算节点数目和每个计算节点数目使用的core数当做变量,测试浮点矩阵A(1000x250),浮点矩阵B(250x200)相乘,结果曲线如下(关于曲线的变化,考虑通信cost)。

固定节点数目(nodes=4),每个计算节点使用的core数做自变量:

1

横坐标表示每个节点数使用的core数目,纵坐标表示加速比。

2

下图是计算节点数做自变量的结果(固定core=8):

3 4

详细的内容还是要读代码。在每个计算节点,可以采用OpenMP或者CUDA继续加速,我们的集群每个计算节点上还有两块K80!这里给出一个CUDA矩阵相乘的测试代码

参考:

1.并行算法设计与性能优化,刘文志

2.CUDA并行程序设计-GPU编程指南,Shane Cook