mpi编程入门
成考报名 发布时间:12-30 阅读:
mpi编程入门篇一
《MPI编程基础》
mpi编程入门篇二
《MPI编程入门&MPI编程进阶》
MPI编程入门
一、 MPI概述
1.1 MPI的发展史
MPI标准化涉及到大约60个国家的人们,他们主要来自于美国和欧洲的40个组织,这包括并行计算机的多数主要生产商,还有来自大学、政府实验室和工厂的研究者们。1992年4月,并行计算研究中心在Williamsburg,Virginia,召开了一个关于消息传递的标准的工作会议,会议上讨论了标准消息传递的必要的、基本的特点,并建立了工作组继续进行标准化工作。
1992年10月,MPI的初步草稿MPI1形成,MPI1主要包含的是在Williamsburg工作组会议上讨论的基本消息传递的接口,因为它的基本目的就是促进讨论并继续此项工作,所以它主要集中在点对点的通信。1993年1月,第一届MPI会议在Dallas举行,1993年2月MPI1修定版本公布;之后定期召开了一系列关于MPI的核心的研讨会;1993年11月MPI的草稿和概述分别发表于Supercomputing'93和the proceedings。直到1994年5月,MPI标准正式发布。1994年7月发布了MPI标准的勘误表。
现在该工作组正在着手扩展MPI、完善MPI,从事于MPI2(MPI的扩展标准)的制定工作。
1.2 MPI的优点
●可移植性和易于使用。以低级消息传递程序为基础的较高级和(或)抽象程序所构成的分布存储通信环境中,标准化的效益特别明显。
●MPI是被正式的详细说明的:它已经成为一个标准。消息传递标准的定义能提供给生产商清晰定义的程序库,以便他们能有效地实现这些库或在某些情况下为库程序提供硬件支持,因此加强了可扩展性。
●MPI有完备的异步通信:使得send,recieve能与计算重叠。
●可以很有效的在MPP上或Cluster上用MPI编程:MPI的虚拟拓扑反映了应用程序所申请的一组结点的通信模式,在MPP上实现的MPI便可以利用这种信息来优化处理器间的通信路径。
1.3 主要内容
●点对点通信(point_to_point communication)
●群体操作(collective operations)
●进程组(process groups)
●通信上下文(communication contexts)
●进程拓扑结构(process topologies)
●与Fortran 77和C语言的邦定(bindings for Fortran 77 and C)
●环境的管理与查询(environmental management and inquiry)
●轮廓管理(profiling interface)
1.4 MPI的各种实现
在国外有许多自从MPI标准制定以来在各种机器上的MPI的portable的实现,并且他们仍从事于自己的MPI实现的性能改进,其中最著名的一些见表1。
表1 国外MPI的各种实现
二、 MPI入门介绍
以下均以MPICH为例。
2.1 MPI的编程方式
对于基本的应用,MPI同其它消息传送系统一样易于使用。下面是一个简单的基于C语言的MPI样本代码。它是SPMD方式的,即每个进程都执行该程序,通过返回的进程编号来区分不同的进程。该程序完成进程0向进程1传递数据buf。
/* first.c */
#include "mpi.h" /*MPI的头函数,提供基本的MPI定义和类型*/
#include <stdio.h>
int main( argc, argv )
int argc;
char **argv;
{
int rank, size, tag=333;
int buf[20]
MPI_Status status
MPI_Init( &argc, &argv ); /*MPI的初始化函数*/
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
MPI_Comm_size( MPI_COMM_WORLD, &size );
if (rank==0)
MPI_Send( buf, 20, MPI_Int, 1, tag, MPI_COMM_WORLD);
if (rank==0)
MPI_Recv( buf, 20, MPI_Int, 0, tag, MPI_COMM_WORLD, &status); /*从进程0接收buf*/
MPI_Finalize(); /*MPI的结束函数*/
return 0;
} /*发送buf到进程1*/ /*该进程的编号*/ /*总的进程数目*/
2.2 MPI的基本语句介绍
1、MPI世界
进程由一个唯一的“标识数”(整数)表示,进程的标识数为数0、1、2、„„、N-1。MPI_COMM_WORLD指“MPI应用中的所有进程”,它称为通信子,并且提供消息传递
所需的所有信息。可移植库对通信子做更多的工作,以提供大多数其它系统所不能处理的同步保护。
2、进入和退出MPI
与其它系统一起,提供两个函数来初始化和结束MPI进程:
int MPI_Init(int *argc, char ***argv) /*初始化*/
int MPI_Finalize(void) /*结束*/
3、我是谁?他们是谁?
典型地,并行程序中的进程需要知道它是谁(它的标识数)以及其它进程是怎样存在的。一个进程通过调用MPI_Comm_rank( )来发现它自己的标识数,用MPI_Comm_size( )来返回进程总数:
int MPI_Group_size(MPI_Group group, int *size)
int MPI_Group_rank(MPI_Group group, int *rank)
4、发送消息
消息是一组给定数据类型的元素。消息被发给一个指定的进程,而且用一个由用户说明的标识来标记。标识用来区分不同的由一个进程所能发送/接受的消息类型。
int MPI_Send(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
5、接受消息
接受进程说明标识和发送进程的标识数。MPI_ANY_TAG和MPI_ANY_SOURCE可选地用于接受任意标识和从任意发送进程而来的消息。
int MPI_Recv(void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)
有关所接受消息的信息在一个状态变量status中返回。
通过这些函数,你会准备编写任意的应用。在MPI中有许多其它、更特异的函数,但是迄今为止所有这些函数可以在这里提到的函数上构造。
2.3 MPI的环境设置
在并行机上的环境一般是设置好的,不需要变动。而在NOW上运行MPI程序需要设置一些配置文件:
1、 由于加载程序到结点上运行调用了Unix系统的rsh命令,所以需要在每个结点上设
置 .rhosts文件,以使rsh能正确执行;
2、 由于NOW环境的异构性,需要在启动时指定运行结点的体系结构;若未指定,是指使
用与启动并行程序的结点具有相同体系结构的结点。在启动并行程序的机器里,具有相同体系结构的几台机器的名字存放在一个名为$MPICH/util/machines/machines.<arch>的文件中,一台机器的名字占有文件的一行,其中$MPICH是一个环境变量,指明MPICH软件安装后所在的目录。并行程序加载运行时是按照文件中机器名字的先后顺序依次加载的。
2.4 MPI的编译和运行
对于简单的程序,可以使用专门的编译命令。对于大的项目,最好使用标准的Makefile。MPICH提供的编译命令有mpicc和mpif77,它们分别是C和Fortran的编译命令:
mpicc -o first first.c
mpif77 -o first firstf.f
对于编译得到的目标程序,运行的命令为:
mpirun –arch xxx –np yyy first
其中xxx为machines.<arch>的<arch>,yyy为申请的进程数目。
2.5 例子
1、 环的C语言实现
#include "mpi.h"
#include <stdio.h>
#define T_SIZE 2000
int main(argc,argv)
int argc;
char *argv[];
{
int ierr, prev, next, tag, rank, size;
MPI_Status status;
double send_buf[T_SIZE], recv_buf[T_SIZE];
MPI_Init(&argc,&argv);
MPI_Comm_rank( MPI_COMM_WORLD, &rank);
MPI_Comm_size( MPI_COMM_WORLD, &size);
next = rank + 1;
if (next > size) next = 0;
prev = rank – 1;
if (prev < 0) prev = size – 1;
if (rank == 0) {
MPI_Send(send_buf, T_SIZE, MPI_DOUBLE, next, tag, MPI_COMM_WORLD);
MPI_Recv(recv_buf, T_SIZE, MPI_DOUBLE, prev, tag+1, MPI_COMM_WORLD, status); } else {
MPI_Recv(recv_buf, T_SIZE, MPI_DOUBLE, prev, tag, MPI_COMM_WORLD, status); MPI_Send(recv_buf, T_SIZE, MPI_DOUBLE, next, tag+1, MPI_COMM_WORLD);
}
MPI_Finalize();
}
2、 环的Fortran语言实现
program ring
include 'mpif.h'
integer ierr
call MPI_INIT(ierr)
call test_ring
call MPI_FINALIZE(ierr)
end
subroutine test_ring
include 'mpif.h'
integer T_SIZE
parameter (T_SIZE=2000)
integer ierr, prev, next, tag, rank, size, status(MPI_STATUS_SIZE)
real send_buf( T_SIZE ), recv_buf ( T_SIZE )
call MPI_COMM_RANK( MPI_COMM_WORLD, rank, ierr )
call MPI_COMM_SIZE( MPI_COMM_WORLD, size, ierr )
next = rank + 1
if (next .ge. size) next = 0
prev = rank - 1
if (prev .lt. 0) prev = size - 1
if (rank .eq. 0) then
call MPI_SEND(send_buf, T_SIZE, MPI_REAL, next, tag, MPI_COMM_WORLD, ierr)
call MPI_RECV(recv_buf, T_SIZE, MPI_REAL, prev, tag+1, MPI_COMM_WORLD, status, ierr) else
call MPI_RECV(recv_buf, T_SIZE, MPI_REAL, prev, tag, MPI_COMM_WORLD, status, ierr) call MPI_SEND(recv_buf, T_SIZE, MPI_REAL, next, tag+1, MPI_COMM_WORLD, ierr) end if
3、 PI的C语言实现
#include "mpi.h"
#include <stdio.h>
#include <math.h>
double f(a)
double a;
{
return (4.0 / (1.0 + a*a));
}
int main(argc,argv)
int argc;
char *argv[];
{
int done = 0, n=100, myid, numprocs, i;
double PI25DT = 3.141592653589793238462643;
double mypi, pi, h, sum, x, a,startwtime, endwtime;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
if (myid == 0) startwtime = MPI_Wtime();
mpi编程入门篇三
《MPI并行编程及基础指导_PPT》
mpi编程入门篇四
《MPI并行编程入门》
mpi编程入门篇五
《MPI并行编程基础-HMLi》
mpi编程入门篇六
《MPI并行程序设计基础》
mpi编程入门篇七
《MPI并行程序设计基础2010》
mpi编程入门篇八
《MPI基础》
mpi编程入门篇九
《第5讲-MPI并行程序设计初步1》
mpi编程入门篇十
《并行编程--MPI开发入门》
系统环境配置
Win2K Adv Svr + VC6
MPI开发包下载
网上搜索下载MPICH2地址
MPI开发包安装
下载完毕,开始安装MPICH2开发包,提示需要.NET 1.1 框架。鉴于本人对VS.NET 2003爱好,直接安装了整个开发环境,也可以只安装.NET框架。可以到微软官方网站下载安装包(
环境配置
“我的电脑”path中设置MPICH2的bin目录(%MPICH2%\bin)以便运行mpiexec程序。我的具体设置如下:
VC6开发环境中包含MPICH2开发包的include目录和lib目录。具体步骤:打开VC6,选择”Tools->Options”,在弹出的“Options”对话框中选择Directories选项卡,分别设置如下图:
(设置Include目录%MPICH2%/include)
(设置Lib目录%MPICH2%/LIB) MPICH2环境配置。运行%MPICH2%/LIB下wmpiregister,在注册界面输入本机器用户名和密码以便mpiexec运行程序。
开发第一个程序“Hello World”
经过上面的步骤,MPICH2开发环境已经建立好,下面便可以步入MPICH2的大殿了。开始最简单也是最经典程序“Hello World”,在过程中倒是遇到不少麻烦。
打开VC6,建立一个控制台应用程序,如下图:
依照课本,包含头文件且把代码敲入main函数中。
#include "mpi.h"
#include <cstdio>
int main(int argc, char* argv[])
{
}
MPI_Init(&argc, &argv); printf("Hello World!\n"); MPI_Finalize(); return 0; 编译程序,发现出现很多编译错误,一时间不知道怎么办好。在细看错误,都是一些函数重载错误。原本想修改代码,但是没有全部源代码。再进一步,发现全部是mpicxx.h文件导致的错误,于是想是否MPI_Init等函数与此文件有关。通过搜索包含文字,发现MPI_Init等函数只在mpi.h中定义,于是想办法不包含mpicxx.h文件以避开问题。在mpi.h中发现代码:
#if !defined(MPICH_SKIP_MPICXX)
#include "mpicxx.h"
#endif
#endif