并行计算入门:mpich的安装与测试

在很多应用场景下,我们普遍需要进行并行计算,而不仅仅是并发。举个例子,比如机器学习中,我们常常使用GPU来并行训练神经网络;在例如Hadoop这种大数据计算平台等分布式系统中,不同的计算机之间,程序的执行也是并行的;同一台计算机中,多核处理器的不同CPU内核之间的计算也是并行的,系统可以此来均衡负载以及提高速度。那么,当我们有需要的时候,也可自己通过编写并行程序来进行计算,以实现我们所需要的功能,MPI就是这样的一个框架。

并行计算是多个可运算的单位同时进行计算的一种计算方式,区别于并发,并发是一般通过分时系统的时间片轮转以达到看起来并行运行的效果。并发执行时,时间开销与串行基本相同,甚至要更大,而并行计算一般来说,有着明显的速度提升,为此,专门有一个公式来描述这种速度的提升,那就是加速比:

rate = (串行执行时间 ÷ 并行执行时间) × 100%

画图形象地概括就是:

但是,一般来说,加速比不会超过并行的进程数,比如说:双进程并行计算耗时一般是大于串行耗时的一半的,一个很重要的原因是,并行计算时,要用到进程间的通信机制,而这个通信过程,是有开销的。其次,多个进程的调度等其他的方面,比如对内外存的竞争访问,也存在着时间开销,导致加速比往往达不到原来的倍数。

不过,问题来了,不同的进程内,甚至不同的线程内,其内部的数据是无法互相访问的。这就造成了一个问题,需要进行进程通信机制。然而不同的机器上的进程,普通的进程间通信机制也不能起作用了,只能通过网络套接字进行。这又造成了一个问题,就是,不同场景下,并行计算的通信接口不一致,这为程序设计带来了一定的麻烦。为了解决这个麻烦,消息传递接口(Message Passing Interface)MPI就诞生了。

MPI不是一个软件,而是并行计算中的一个软件标准,它规定了统一的程序接口,而对于单机模式不同进程间,多机模式不同计算机之间,通信都可以使用统一的函数调用来进行,这极大地方便了程序的编写。

MPI程序是基于消息传递的并行程序。消息传递指的是并行执行的各个进程具有自己独立的堆栈和代码段,作为互不相关的多个程序独立执行,进程之间的信息交互完全通过显示地调用通信函数来完成。

MPI有多种版本的实现,最常用的有MPICH和OpenMPI两种,以及微软的MS-MPI。其中,MPICH由于某些原因,对windows系统的最高版本支持已经停留在了MPICH2-1.4版,而此时2018年03月26日的最新版本已经到了3.2了。我在windows10系统中并不能成功安装注册MPICH软件,甚至win7中也很难成功,而linux系统中安装就非常简单快速,可能这就是新版不再支持windows的原因。

MPICH官网下载地址:

http://www.mpich.org/downloads/

进去之后找合适的版本下载即可,手动安装过程网上一搜一大堆,这里不再赘述。如果你的Linux源中包含mpich的话,可以直接通过源安装。

Ubuntu系统可通过以下命令安装,其他系统同理

sudo apt install mpich

安装后,当mpicc、mpic++、mpiexec这三个命令可以使用的时候,就是安装成功了。我们可以使用C、C++通过调用mpich来编写并行程序了。

什么?你选择Python?那就再安装一个mpi4py吧!linux系统中执行以下命令即可:

sudo pip3 install mpi4py

为了验证mpich是否安装成功,我们可以使用简单的代码来验证一下。

#include<stdio.h>
#include"mpi.h"

int main(int argc, char *argv[]){
        int totalTaskNum, rankID;

        int rt = MPI_Init(&argc, &argv);
        if(rt != MPI_SUCCESS){
                printf("Error starting MPI.\n");
                MPI_Abort(MPI_COMM_WORLD, rt);
        }

        MPI_Comm_size(MPI_COMM_WORLD, &totalTaskNum);
        MPI_Comm_rank(MPI_COMM_WORLD, &rankID);

        printf("Hellow, world! %dth of totalTaskNum = %d\n", rankID, totalTaskNum);

        MPI_Finalize();

        return 0;
}

编译和运行时,和普通C语言程序稍稍有所区别:

mpic++ 1.cpp –o 1.out
mpiexec –n 4 ./1.out

其中,mpiexec的-n参数是用来指定执行时的进程数的,4表示设定为4个进程。这些进程在执行时会被自动调度,单机时会尽可能均匀分布在机器上不同的CPU运算单元中,多机时,会均匀分布在不同的计算机中。执行上述命令后,即可看到运行效果,如果没有效果,那就是安装不成功。

python中将以下代码保存为py文件。

from mpi4py import MPI

comm = MPI.COMM_WORLD
rank = comm.Get_rank()

if rank == 0:
    data = {'a': 7, 'b': 3.14}
    data2 = 'hello world'
    comm.send(data2, dest=1, tag=11)
    comm.send(data2, dest=2, tag=11)
    comm.send(data2, dest=3, tag=11)
elif rank == 1:
    data = comm.recv(source=0, tag=11)
elif rank == 2:
    data = comm.recv(source=0, tag=11)
elif rank == 3:
    data = comm.recv(source=0, tag=11)

print("rank",rank,data)

执行命令:

mpiexec -n 4 python3 1.py

然后同样,可以看到运行输出效果。

 

打赏作者
很喜欢这篇文章,赞赏一下作者,以激励其创作出更多好文!

您的支持将鼓励我们继续创作!

[微信] 扫描二维码打赏

[支付宝] 扫描二维码打赏

分享到社交网络:

发表评论

电子邮件地址不会被公开。 必填项已用*标注