并行编程之MPI (一)

来源:互联网 发布:是京东好还是淘宝好 编辑:程序博客网 时间:2024/05/15 01:55

大部分并行多指令多数据(MIMD - Multiple Instruction, Multiple Data)都分为分布式内存系统和共享内存系统两种。在共享内存系统中,一组自治的处理器通过互联网络与一个全局的内存系统连接,每个处理器都能够访问每个内存区域,MPI是为此类系统编程设计的框架接口,而在分布式内存系统中,每个处理器有自己的私有内存空间,处理器-内存对之间通过互联网络来相互通信,OpenMP和Pthreads是为此类系统设计的。

本文是关于MPI的入门记录:

1. 从网站下载安装包: http://www.mpich.org:

2. 解压:

tar zxf mpich-3.2.tar.gz

3. 创建软件安装目录,我习惯在用户目录下创建usr来存放自己安装的软件:

mkdir /root/usr/mpich3.2

4. 创建编译目录,这样和源码目录区分开,保持了源码目录的干净:

mkdir -p /tmp/root/mpich_build

5. 配置以产生Makefile文件:

cd /tmp/root/mpich_build 

/root/mpich-3.2/configure -prefix=/root/usr/mpich3.2 |& tee configure_output.txt

下面是安装手册说明的额外可选配置参数:

报错,提示缺少C编译器 -> apt install -y gcc:

重新配置,如下错误,安装Fortran编译器 -> apt install -y gfortran:(yum方式安装为: yum install -y gcc-gfortran)

重新配置,提示需要安装c++编译器:apt install -y g++

重新配置无错,可以下一步

6. 编译:

make |& tee make_output.txt

7. 安装:

make install |& tee install_output.txt

8. 环境变量配置:

vim /root/.bash_profile

-> export PATH=/root/usr/mpich3.2/bin:$PATH

source /root/.bash_profile

---------------------------

9. 编写简单程序测试MPI:

这里编写一个MPI小程序,用一个进程0专门来负责接收其他进程的消息并打印出来,其他进程(1, ...)负责产生消息并发给进程0打印输出,代码如下:

使用mpicc编译:

使用mpiexec运行程序,-n参数用于指定使用多少个进程运行:

可以看到,只有1个进程时没有消息接收,直接退出,在5个进程时,1到4号进程都把消息发给了进程0。

可见,使用MPI,当进程运行后,它可以保证进程间可以互相通信。

10. 代码解析:

Line 3:         MPI.h包含了MPI函数的原形、宏定义、类型定义等,还包括了编译MPI程序所需要的全部定义与声明。

Line13:        MPI_Init()需要在其他MPI函数调用前调用,它会对MPI环境进行所需要的初始化配置,参数为argc和argc,(MPI_Init(&argc, &argv);)不需要用到则为NULL

Line14~15: 使用MPI_COMM_WORLD告知进程数和进程号

Line17~28: 单程序多数据流(SPMD - Single Programm, Multiple Data)的体现,根据判断进程号来执行不一样的逻辑,这里进程0负责接收其他进程发来的,消息tag为0的消息并打印,使用tag来区分消息,可以根据tag执行不同的操作,其他进程就发消息给进程0,这里用到了两个MPI函数: MPI_Send 和 MPI_Recv

(API链接: http://www.mpich.org/static/docs/latest/)

MPI_Send官网说明如下:

         MPI_Recv官网说明如下:

使用MPI_Recv有一个缺陷:如果一个进程试图接收消息,但没有相匹配的消息,那么该进程就会永远被阻塞,即进程悬挂,因此,编程时需要注意每条接收都有对应标签的发送)

大多数时候,只要满足data_type(如上面代码的: MPI_CHAR)一样,同时接收数据缓冲区大于等于发送数据字节数,那么,进程A发送的消息就可以被进程B所接收。

Line30:       MPI环境资源释放 

0 0
原创粉丝点击