RHEL5 下利用MPICH2配置并行运算集群
李剑,罗元成
(重庆工程职业技术学院计算机系,重庆 400037)
摘 要:MPICH是国内常用的集群计算消息传递系统。本文描述了MPI的基本概念及实现软件MPICH2,介绍了在Linux环境下如何构架基于 MPICH的高性能计算集群系统的方法,给出了具体的步骤和基本配置过程。实验结果表明:在现有并行集群系统下能有效地利用现有计算机资源,大幅度提高计算效率,为一些复杂问题的求解提供可行方案。
关键字:并行计算;MPI;MPICH; 集群
中图分类号:TP393.02 文献标识码: A
Configure Parallel Computing Cluster by MPICH2 Based on RHEL5
LI Jian,LUO Yuan-cheng
(Chongqing Vocational Institute of Engineering,computer department,ChongQing 400037)
Key words:parallel computing;MPI;MPICH;cluster
随着工作站和PC机性能的提高和网络技术的发展,集群系统(Cluster)是近年来人们开始研究的一种新计算机系统,也称网络并行计算系统,是利用高速通讯网络将一组高性能工作站或PC机连接起来而形成的一种分布式并行计算系统。它通常采用消息传递(Message Passing)的方式进行并行计算。消息传递接口(MPI - Message Passing Interface) 作为并行编程模型的代表和事实上的标准, 已经在越来越多的集群高性能计算中得到了使用。
MPI消息传递过程分为三个阶段: ⑴消息装配,将发送数据从发送缓冲区中取出, 加上消息信封等形成一个完整的消息; ⑵消息传递,将装配好的消息从发送端传递到接收端; ⑶消息拆卸, 从接收到的消息中取出数据送入接收缓冲区。如图所示, 整个传递过程可划分为三个层次: MPI 层、内核层和网络接口层。MPI层处于整个传输的顶部, 为用户提供一个透明通用的函数库, 来完成用户程序的通信操作。内核层起到一个承上启下的作用, 向上为MPI 层提供socket 接口函数, 向下为网络接口程序准备skb 数据空间。网络接口层与网络设备直接相连, 处于传输的最底层, 向上为内核层提供抽象的网络设备结构, 屏蔽不同网络设备的区别, 实现网络设备的统一管理。
图1 MPI消息传递过程
MPI是为开发基于消息传递模型的并行程序而制定的工业标准,其目的是为了提高并行程序的可移植性和易用性。参与MPI标准制定的人员来自欧美40多个组织,大部分主要的并行计算机制造商、大学研究所、政府实验室、工业组织等都投入到MPI标准化工作。有了统一的并行编程语言标准,并行计算环境下的应用软件及软件工具就都能够实现透明的移植,各个厂商就可以依据标准提供独具特色和优势的软件实现和软件支持,从而提高了并行处理的能力。
MPI只是一个并行编程语言标准,要编写基于MPI的并行程序,还必须借助某一MPI具体实现。MPICH是Linux平台下最重要的一种MPI实现,是一个与MPI规范同步发展的版本。LAM(Local Area Multicomputer)是Linux平台下另一免费的MPI实现。它由Ohio州立大学开发,主要用于异构的网格计算并行系统。
MPICH是可以免费从http://www-unix.mcs.anl.gov/mpi/mpich 取得,更为重要的是,MPICH是一个与MPI-1规范同步发展的版本,每当MPI推出新的版本,就会有相应的MPICH的实现版本。MPICH2是 MPI(Message-Passing Interface)的一个应用实现,支持最新的MPI-2接口标准,是用于并行运算的工具,与之前版本相比MPICH2具备更加严谨和合理的结构,可移植性和效率更好,在程序设计语言上支持C/C++和Fortran。MPICH2的主页是http://www-unix.mcs.anl.gov /mpi/mpich2/index.htm,在这个页面上就能找到各平台最新版本MPICH2的下载地址,其中还包括源代码。最新源代码链接的地址是 ftp://ftp.mcs.anl.gov/pub/mpi/mpich2-1.0.8.tar.gz。在ftp://ftp.mcs.anl.gov /pub/mpi下还有MPICH2的安装和使用指南文档,主要有三个,分别是User's Guide,Installer's Guide和Windows Developer's Guide。
1 准备工作:
1.1 设置IP,更改主机名为station1,station3,station6,station8
pc
主机名
IP
节点1
station1
172.17.2.1
节点2
Station3
172.17.2.3
节点3
Station6
172.17.2.6
节点4
Station8
172.17.2.8
以四台pc为例,为了方便,分别更改了四台机器的主机名为station1,station3,station6,station8,以第一台为例:
hostname station1
这只是临时更改主机名,要想永久更改主机名,编辑下面文件:
vim /etc/sysconfig/network
编辑内容为(最后一行就是要改的主机名):
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=station1
更改/etc/hosts文件
#vi /etc/hosts 打开hosts文件,更改如下:
127.0.0.1 localhost.localdomain localhost
172.17.2.1 station1
172.17.2.3 station3
172.17.2.6 station6
172.17.2.8 station8
1.2 创建SSH信任连接(在root目录下)
1.2.1 在station1生成SSH秘钥对
#ssh-keygen -t rsa 一路回车即可
产生.ssh文件,
#ls -a 查看是否有.ssh文件夹
1.2.2进入.ssh目录
#cd .ssh
1.2.3 生成authorized_keys文件
#cp id_rsa.pub authorized_keys
1.2.4 退出到root目录
#cd ..
1.2.5 建立本身的信任连接
#ssh station1 按提示输入yes
1.2.6 设置station3(station3的root目录下)
#ssh-keygen -t rsa 生成.ssh文件夹
#scp 172.17.2.1:/root/.ssh/* /root/.ssh 拷贝station1上的.ssh文件夹覆盖本地的
#scp 172.17.2.1:/etc/hosts /etc/hosts 拷贝station1上的hosts文件覆盖本地的
#ssh station1 提示处输入yes回车
设置station6,station8的方法与station3相同
1.2.7 确认四台机器的信任连接已建立
对每个节点执行:
#ssh station1
#ssh station3
#ssh station6
#ssh station8
在提示处输入yes回车,最后确定无需输入密码并且没有任何提示信息即可登陆("Last login:时间日期"提示信息除外)
2 安装mpich2
2.1 到MPICH官方网站下载源代码包,解压缩
#tar -zxvf mpich2-1.0.8.tar.gz
2.2 进入mpich2解压目录
#cd mpich2-1.0.8
2.3 设置安装目录
#./configure --prefix=/usr/loca/mpich
2.4 编译
#make
2.5 安装
#make install
2.6 改变目录
#mv mpich2-1.0.8 /usr/local/mpich/install
2.7 退出到root目录
#cd
2.8 通过编辑.bashrc文件修改环境变量
#vim .bashrc
修改后的.bashrc文件如下:
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
PATH="$PATH:/usr/local/mpich/bin" #新增加的
#Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
2.9 测试环境变量设置
#which mpd
#which mpicc
#which mpiexec
#which mpirun
2.10 修改/etc/mpd.conf文件,内容为secretword=myword
#vi /etc/mpd.conf
设置文件读取权限和修改时间
#touch /etc/mpd.conf
#chmod 600 /etc/mpd.conf
2.11 创建主机名称集合文件/root/mpd.hosts
#vi mpd.hosts
文件内容如下:
station1
station3
station6
station8
3 测试
3.1 本地测试
启动:
#mpd &
[1] 24455
观看启动机器:
#mpdtrace
station1
退出:
#mpdallexit
3.2运行集群系统
#mpdboot -n 4 -f mpd.hosts
参数-n 4指定了要起动的机器个数,-f mpd.hosts指定了通过mpd.hosts运行
#mpdtrace
station1
station6
station3
station8
#mpdallexit
3.3测试运行MPICH的圆周率的程序
在软件的安装包里有圆周率计算的原代码icpi.c,先编译成可执行文件
#cd /usr/local/mpich/install/examples/
mpicc icpi.c -o icpi
3.1 集群测试
#mpdboot -n 4 -f mpd.hosts
启动这四台机器
#mpiexec -n 4 /usr/local/mpich/install/examples/icpi
用num指定使用的进程数
Enter the number of intervals: (0 quits) 100000000
pi is approximately 3.1415926535901937, Error is 0.0000000000004006
wall clock time = 18.460739
Enter the number of intervals: (0 quits) 10000
pi is approximately 3.1415926544231239, Error is 0.0000000008333307
wall clock time = 0.022534
Enter the number of intervals: (0 quits) 0
#mpdallexit
3.2 单机测试
#cd /usr/local/mpich/install/examples/
#./icpi
Enter the number of intervals: (0 quits) 100000000
pi is approximately 3.1415926535902345, Error is 0.0000000000004414
wall clock time = 73.898167
Enter the number of intervals: (0 quits) 10000
pi is approximately 3.1415926544231341, Error is 0.0000000008333410
wall clock time = 0.010941
测试结果表明:在intervals的值设为100000000,既精确值比较大时,群集的4进程并发运行时间是18.460739秒,单机单进程运行时间是73.898167秒,明显快很多,并行运算还是很有效果的。在intervals的值设为10000,既精确值比较小时,群集的4进程并发运行时间是0.022534秒,单机单进程运行时间是0.010941秒,这是因为并行运算过程中,参与运算的机器需要通过网络传递一些消息,如果计算量不大的话,花在了这上面的时间影响会比较明显,因而反不如单机的来得快。
4 查错
4.1 通过mpdcheck获得帮助信息
#mpdcheck -pc
4.2 查错
#mpdcheck -l
4.3 通过mpd.hosts文件查错
#mpdcheck -f mpd.hosts
如果无错误
#mpdcheck -f mpd.hosts -ssh
4.4 对任意两台机器进行查错
Station1上:
#mpdcheck -s
返回主机名host和端口port
server listening at INADDR_ANY on: station1 40782
station3上:
# mpdcheck -c 172.17.2.1 40782
client successfully recvd ack from server: ack_from_server_to_client
station1 上返回结果
server has conn on <socket._socketobject object at 0xb7ffe35c> from ('172.17.2.3', 54438)
server successfully recvd msg from client: hello_from_client_to_server
返回消息传递结果
4.4 mpd查错
station1上:
#mpd -e &
返回使用的端口
[1] 14065
[root@station1 ~]# mpd_port=41563
station3上:
# mpd -h station1 -p 41563 &
[1] 5122
以上测试通过,集群系统就建成了。
5 结束语
利用局域网和MPI可以构建由PC组成的廉价、实用且性能优良的并行计算机。文中利用普通PC机在Linux环境下构建了基于MPICH2的高性能计算集群系统,并对其进行了高性能测试。实验结果表明这种构建高性能计算集群系统的方法切实可行,不但可以节省计算时间,提高计算精度,而且可以解决单机无法完成的超大规模求解问题。并行计算使用多台计算机或者具有多个处理器的计算机来求解问题,从而为求解大规模复杂问题提供了可能。作为一个优秀的操作系统,Linux特别适合用来组建并行计算平台。
参考文献:
[1] William Gropp and Ewing Lusk in Mathematics and Computer Science Division
Argonne National Laboratory. MPICH2的安装和使用指南文档[EB/OL],ftp://ftp.mcs.anl.gov/pub/mpi/ mpich2-doc-install.pdf.
[2]徐巍,李玉榕.MPICH在PC集群系统中的运用[J].福建工程学院学报,2006-4.
[3]高飞,刘青昆,向文,黄丹.MPICH标准通信模式下消息传递机制的研究[J].长春师范学院学报(自然科学版),2007-10.
[4]庞丽萍,何飞跃,岳建辉等.并行文件系统集中式元数据管理高可用系统设计[J].计算机工程与科学,2004, 26 (11): 87-88.
MPICH2是与MPI-2相对应的MPICH实现版本,包含了MPI-2相对于MPI-1扩充后的一些功能,比如动态任务管理,并行I/O等。当前最新版本是MPICH2-1.0.2.
(1)下载MPICH2源程序包mpich2-1.0.2p1.tar.gz(http://www-unix.mcs.anl.gov/mpi/mpich2/)。
(2)解压源程序包到当前目录下:tar zxf mpich2-1.0.2p1.tar.gz,此时会得到一个名为mpich2-1.0的子文件夹。
(3)创建一个安装目录(比如/home/transim/mpich2,默认为/usr/local/bin),为了以后使用方便,可以将此安装 目录共享到其他所有将要运行mpich2的节点机上;否则就需要分别在其他机器上安装mpich2。如果不创建安装目录,则在下面的configure步 骤中会自动创建安装目录。
(4)选择一个编译目录,最好将编译目录与源代码目录分离开,以便能保持一个干净的源代码用来在其他机器上重新安装。比如将源代码拷贝到/tmp /mpich2下。
(5)配置MPICH2,指定安装目录,并在编译目录下运行configure脚本。
如:cd /tmp/mpich2
./configure –prefix=/home/transim/mpich2 2>&1 | tee configure.log
(6) 编译链接MPICH2:make 2>1& | tee make.log
(1)安装MPICH2:make install 2>1& | tee install.log
(2)将安装目录中子目录bin加入到环境变量PATH中:
setenv PATH /home/transim/mpich2/bin:$PATH (csh或tcsh)
export PATH=/home/transim/mpich2/bin:$PATH (bash或sh)
用以下命令检查安装是否成功:
which mpd
which mpicc
which mpiexec
which mpirun
所有以上的命令都应该指向安装目录的bin子目录。此外,如果没有用NFS来共享安装目录,则需要将bin子目录拷贝到其他每台机器上。
(9)与MPICH不同的是,MPICH2使用一个外部进程管理器来启动MPI任务,默认管理器为MPD。为了安全考虑,MPD需要搜索用户主目录 下的文件.mpd.conf,文件中包含:secretword=<secretword>,其中secretword应该是一个只有用户知 道的字符串(最好不要与用户密码相同),将此文件权限设置为只有所有者可读及可写。
(10)用以下命令检查测试MPICH2在本机是否已正确安装并可以启动:
Mpd & (启动mpd)
Mpdtrace (输出应该是本机机器名)
Mpdallexit (退出mpd)
(11)在mpd下运行非mpi程序测试:
mpd &
mpiexec –n 1 /bin/hostname (输出本机机器名)
mpdallexit
(12)配置所有机器,使用机器间采用rsh或ssh互相访问时不需要输入密码。配置完后可用以下命令进行测试:
ssh hostname date 或 rsh hostname date
(13)使用mpd.hosts文件来启动文件所列机器上的mpd:
mpdboot –n <number to start> -f mpd.hosts
在以上命令行中所要启动的机器数量必须小于等于mpd.hosts文件中所列的机器数,即使同一台机器名在文件中出现多次,默认情况下在每台机器上只启动一个mpd。在各台机器启动mpd后,运行mpdtrace,应该输出每台机器的机器名称。
若不能启动所有机器上的mpd,可采用手动方法来启动,方法如下:
在本地机器上运行:
mpd & (启动本地mpd守护进程)
mpdtrace –l (输出本地mpd守护进程的主机名及端口号)
然后登录到其他机器,运行:
mpd –h <hostname> -p <port> &
hostname及port都为刚才输出的本地机器名及端口号。可以用mpdtrace命令检查哪些机器已经加入到mpd环中。
(14)用mpdtrace命令检查是否所有机器都已启动mpd,然后用mpdringtest命令测试在环中传递一个消息,如:
mpdringtest 100
mpdringtest 1000
(15)有环中测试运行多进程任务:
mpdrun –n <number> hostname
其中number不一定非要等于机器数。
(16)用mpiexec命令运行MPI任务,可以用程序包自带的cpi例子:
mpiexec –n 5 cpi
关于mpiexec命令更多选项可运行mpiexec --help来查看。
MPI2与MPI1的不同之处:
原来在MPI1中configure命令的一些选项参数在MPI2中必须用环境变量的形式来定义,比如选项参数-cc=<compile- name>必须改为setenv cc <compile-name>。原来在MPICH1中不以--enable或--with开关的选项参数在MPICH2中都要定义成环境变量 的形式。
此外,在进程管理器的处理及通信设备的选择上也有所不同。
MPICH2中的进程管理器
在MPICH2中用一种叫做PMI的接口将MPICH2的代码库与进程管理器分离开来,有三种进程管理器可供选择:mpd,smpd及 gforker。
mpd是默认的进程管理器,它由一个守护进程环组成。
smpd支持windows和linux版本,它是在windows版本的MPICH2中所唯一包含的进程管理器。
gforker在一台单独的机器上启动所有的进程,对调试程序及共享存储的多处理器主机上较有用。
Configure命令中的两个选项参数:
--enable-thread=multiple (使用多线程)
--enable-cxx (使用c++语言绑定)
--enable-timing=none/all/runtime (定义是否加入计时功能)
MPICH2中程序的编译与链接
在MPICH2中,C、C++、FORTRAN77、FORTRAN90对应的默认编译命令分别是mpicc、mpicxx、mpif77、 mpif90,可以通过设置MPICH_CC、MPICH_CXX、 MPI_F77、MPICH_F90的值来指定编译器。
由于在stdio.h及mpi的C++接口中都定义了SEEK_SET,SEEK_CUR,SEEK_END,所以在编译采用mpi的c++程序时会出错,解决方法是在源代码中,#include <stdio.h>之前取消以下宏定义:
#undef SEEK_SET
#undef SEEK_ CUR
#undef SEEK_ END
另一种方法就是在命令行中加入:-DMPICH_IGNORE_CXX_SEEK选项。
MPICH2中程序的调试
可以在mpiexec命令中加入-gdb选项来使用调试器gdb调试程序,用-gdba选项来将一个正在运行的程序附加到调试器中。若使用 totalview来调试程序,需要使用选项参数-tv。
PBS specifies the machines allocated to a particular job in the file $PBS NODEFILE.
But the format used by PBS is different from that of MPD. Specifically, PBS
lists each node on a single line; if a node (n0) has two processors, it is listed
twice. MPD on the other hand uses an identifier (ncpus) to describe how
many processors a node has. So, if n0 has two processors, it is listed as n0:2.
One way to convert the node file to the MPD format is as follows:
sort $PBS NODEFILE | uniq -C | awk ’{ printf(”%s:%s”, $2, $1); }’ >
mpd.nodes
Once the PBS node file is converted, MPD can be normally started
within the PBS job script using mpdboot and torn down using mpdallexit.
mpdboot -f mpd.hosts -n [NUM NODES REQUESTED]
mpiexec -n [NUM PROCESSES] ./my test program
mpdallexit
1.