湖南大学SCCI并行计算组-MPI并行编程教程-01

湖南大学SCCI并行计算组
MPI并行编程教程01

一、学习的大致内容:

  1. MPI概述
  2. MPI实现
  3. 终极测试

  注:此部分内容提炼自《并行程序设计导论》第三章


二、MPI的概述:

  1. MPI的宏观理解
      MPI的英文全称为:Message Passing Interface
      啥意思捏?就是个消息传递的接口,或者说是消息中转服务商。
      假设,我们生活在上世纪80年代,只能写信沟通,我(进程A)想写一封情书(信息)给你(进程B),我写好了情书后(生成好信息),我交给邮递员(MPI函数)帮我装入信封(信息封装),邮递员交给邮政局(MPI的内部缓存),邮政局交给邮递员(MPI函数)再交给你(进程B),在交给你之前,邮递员还会帮你拆开信封(解封)只将里面的情书(信息)传递给你(进程B)。
      其实与计算机网络中应用层之间信息的转递是一个模式,只是MPI不需要像网络层次结构那样层层封装传递。

  1. MPI现实理解
      在多进程程序中,两个进程可以通过调用函数来进行通信:一个进程发送函数,另一个接收函数。我们将使用消息传递的实现称为消息传递接口(MPI)。MPI并不是一种新的语言,它定义了一个可以被C、C++和Fortran程序调用的函数库

  1. 头文件
      MPI.h

  1. 编译
      $ mpicc 文件名.c -o 文件名.out

  1. 运行
      $ mpirun -n 进程数 ./文件名.out

  1. 获取版本号
      $ mpicc -v 或 mpiexec --version

三、MPI实现

  我们通过调用一系列的MPI函数来实现多进程间的通信(MPI通信)

1. 开始与结束
  要使用MPI,必须对MPI进行初始化,可以理解为:要让邮递员帮你传情书得自己先建一个邮局。同样的,在你不需要继续使用MPI时,也需要结束MPI,释放MPI所占的资源
  (过河拆桥,情定三生后就拆邮局,想想都刺激)


(0)MPI初始化判断: MPI_Initialized函数:
函数原型:

int MPI_Initialized(int* flag_p)


参数解释:
①int* flag_p:
  flag_p是指向flag的指针。用来判断MPI系统是否已经初始化,若MPI已初始化则flag=true,反之flag=false。


作用:
唯一可在MPI_Init前使用的函数,用来检测MPI系统是否已经初始化。



(1)MPI初始化: MPI_Init函数:
函数原型:

int MPI_Init(int* argc_p,char*** argv_p){...}


参数解释:
①int* argc_p:
  argc_p是指向argc的指针,是main函数中参数的继承(一般写NULL即可)。
②char*** argv_p:
  argv_p是指向argv的指针,是main函数中参数的继承(一般写NULL即可)。
③返回值:
  返回值为int类型的错误码,在大部分情况下,我们忽略这些错误码。亦可以利用MPI_Error_string函数,通过输入错误码返回错误信息的方式得到错误信息。

作用:
  初始化MPI。具体的:为MPI分配缓存,设置MPI中所有进程的序号,等。



(2)MPI结束: MPI_Finalize函数:

函数原型:

int MPI_Finalize(void){...}


参数解释:
  返回值:错误码

作用:
  释放MPI占用的资源


(3)MPI框架:

  有了上述(1)MPI_Init,(2)MPI_Finalize俩函数,则我们可以初步得到一个利用MPI程序设计的框架,即:

int main(int* argc,char** argv){
    /*No MPI Calls Before This*/
    MPI_Init(NULL,NULL);
    ....
    MPI_Finalize();
    /*No MPI Calls After This*/
    return 0;
}

2. 通信子Communicator

(1)通信子
  概念:
  通信子就是一个集合,一个由多个可以相互通信的进程组成的集合。

  MPI通信子类型:
  MPI_Comm,其值为:MPI_COMM_WORLD



(2)获得通信子内进程个数的函数: MPI_Comm_size函数

函数原型:

int MPI_Comm_size(MPI_Comm comm,int* Comm_sz_p){...}


参数解释:
  ①MPI_Comm  comm:  /*输入*/
  comm是MPI通信子的名称,其名称为MPI_COMM_WORLD不变
  ②int*  comm_sz_p:  /*输出*/
  comm_sz_p是一个指针,用来返回通信子大小(进程总数)。
  ③返回值:  /*输出*/
  错误码。

函数作用:
  用comm_sz_p来返回 名叫comm的通信子大小



(3)获得当前调用此函数的进程号: MPI_Comm_rank函数

函数原型:

int MPI_Comm_rank(MPI_Comm comm,int* my_rank_p){...}


参数解释:
  ①MPI_Comm  comm   /*输入*/
  同上,通信子名称:MPI_COMM_WORLD
  ②int*   my_rank_p   /*输出*/
  my_rank_p是一个指针,用来返回当前调用此函数的进程在通信子中的序号。
  ③返回值:  /*输出*/
  错误码。

函数作用:
  用my_rank_p来返回调用此函数的进程在名叫comm的通信子中的序号。



(4)MPI框架:
  有了通信子的新知识,我可以在1-(3)MPI框架的基础上扩展为一个更细的框架。
  由于我们在MPI调用中,不可避免的要大量使用通信子名(MPI_COMM_WORLD),通信子大小(comm_sz),当前进程号(my_rank),则我们将MPI框架构造如下:

#include <stdio.h>//C语言基本头文件
#include <mpi.h>//MPI头文件

/*---设置全球变量----*/
MPI_Comm comm;
int comm_sz;
int my_rank;
/*---SET GLOBAL VARIABLE---*/

int main(int argc,char** argv){
    /*No MPI calls before this*/
    MPI_Init(NULL,NULL);
    
    comm = MPI_COMM_WORLD;//Set comm
    MPI_Comm_size(comm,&comm_sz);//get communicator size
    MPI_Comm_rank(comm,&my_rank);//get this processs rank
    
    
    ...//you can coding whatever you want
    
    MPI_Finalize();
    /*No MPI calls after this*/
}
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值