1.2 MPI基础
MPI的核心是进程间通信,遵循进程间顺序通信模型(CSP)。每个进程在自己的地址空间内运行程序。声明的变量(例如int b[10];)是每个进程的私有变量,变量b在不同的进程中是相互独立的。在MPI中,存在两种主要的通信方式:一是点对点通信,即两个进程间通信;二是聚合通信,即一组进程间通信。
每个MPI进程在每组进程中拥有1个进程号。进程号从0开始,例如4个进程在一组,进程号分别是0、1、2、3。所有的MPI通信都在通信域中进行。通信域包含一组进程和一个(隐藏的)通信文本。通信文本的作用在于保证消息和库的一致性,也是保证MPI应用程序能够使用第三方库的关键。通信域对象是一个隐藏类型,可称之为句柄。在C语言中,通信域句柄是MPI_Comm类型;在Fortran语言中,通信域句柄是TYPE(MPI_Comm)类型(针对Fortran 2008语言)或者INTEGER类型(针对早期的Fortran语言)。在MPI程序中,存在MPI_COMM_WORLD和MPI_COMM_SELF两个预定义的通信域。MPI_COMM_WORLD包含所有MPI进程,MPI_COMM_SELF仅包含运行一个实例程序的进程。MPI提供各种通信域函数,例如MPI_Comm_rank函数用于获取进程号,MPI_Comm_size函数用于获取通信域中的进程数量,以及用于创建新的通信域的函数。
一个简单完整的MPI程序示例如图1-1所示。在图1-1中,MPI_Init函数用于初始化MPI程序,MPI_Finalize函数用于结束MPI程序。除了极个别函数,大多数MPI函数需要在MPI_Init(或者MPI_Init_thread)函数之后和MPI_Finalize函数之前进行调用。在并行程序中,若MPI_Init函数参数无法从main函数中获取命令行参数,则需要通过MPI进行指定。
MPI进程间执行是相互独立的。在图1-1例子中,printf语句按照随机顺序执行,甚至无法保证一次输出一行。
图1-1的例子采用C语言编写,但MPI设计为不专门针对特定的语言。目前,MPI支持C语言(C++程序可调用C语言的接口)和Fortran语言。