MPI并行程序设计
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2013年8月 MPI并行程序设计 10/217
从简单入手!
• 下面我们首先分别以C语言和Fortran语言的 形式给出一个最简单的MPI并行程序Hello (下页). • 该程序在终端打印出Hello World!字样. • “Hello World”:一声来自新生儿的问候.
2013年8月
MPI并行程序设计
• 编译制导标准
– – OpenMP – 可移植共享存储并行编程标准.
• 消息传递库标准
本讨论的重点
– – MPI – – PVM
2013年8月
MPI并行程序设计
5/217
消息传递并行程序设计
• 消息传递并行程序设计
– 指用户必须通过显式地发送和接收消息来实现处理机间的数据交 换。 – 在这种并行编程中,每个并行进程均有自己独立的地址空间,相 互之间访问不能直接进行,必须通过显式的消息传递来实现。 – 这种编程方式是大规模并行处理机(MPP)和机群(Cluster)采 用的主要编程方式。
2013年8月
MPI并行程序设计
2/217
相关网址
• MPI: http://ww.mpi-forum.org, http://www.mcs.anl.gov/mpi • Pthreads: http://www.oreilly.com • PVM: http://www.epm.ornl.gov/pvm/ • OpemMP: http://www.openmp.org • 网上搜索:www.google.com
2013年8月
MPI并行程序设计
9/217
讲座内容提示
• 基本的MPI
– 基本概念 – 点到点通信(Point to point)
• MPI中API的主要内容,为MPI最基本,最重要的内容
– MPI程序的编译和运行
• 深入MPI
– 用户自定义(/派生)数据类型(User-defined(Derived) data type)
::::
Hello World! Hello World! Hello World! Hello World!
19/217
2013年8月
MPI并行程序设计
:开始写MPI并行程序
• 在写MPI程序时,我们常需要知道以下两个 问题的答案:
– 任务由多少个进程来进行并行计算?
– 我是哪一个进程?
2013年8月
– MPI-前缀,且函数名全部为大写.
• MPI函数的参数被标志为以下三种类型:
– IN:参数在例程的调用中不会被修正. – OUT:参数在例程的调用中可能会被修正. – INOUT:参数在一些例程中为IN,而在另一些例程中为OUT.
2013年8月 MPI并行程序设计 14/217
MPI初始化-MPI_INIT
机群应用开发
Parallel Programming: Fundamentals and Implementation
并行编程原理及 程序设计
曙光信息产业有限公司
2013年8月
2013年8月 MPI并行程序设计 1/217
参考文献
• 黄铠,徐志伟著,陆鑫达等译. 可扩展并行计算技术,结构与编程. 北京:机 械工业出版社, P.33~56,P.227~237, 2000. • 陈国良著.并行计算—结构、算法、编程. 北京:高等教育出版社,1999. • Barry Wilkinson and Michael Allen. Parallel Programming(Techniques and Applications using Networked Workstations and Parallel Computers). Prentice Hall, 1999. • 李晓梅,莫则尧等著. 可扩展并行算法的设计与分析. 北京:国防工业出 版社,2000. • 张宝琳,谷同祥等著. 数值并行计算原理与方法. 北京:国防工业出版 社,1999. • 都志辉著. 高性能计算并行编程技术—MPI并行程序设计. 北京:清华大 学出版社, 2001.
int MPI_Init(int *argc, char **argv) MPI_INIT(IERROR)
– MPI_INIT是MPI程序的第一个调用,它完成 MPI程序的所有初始化工作。所有的MPI程序 的第一条可执行语句都是这条语句。 – 启动MPI环境,标志并行代码的开始. – 并行代码之前,第一个mpi函数(除 MPI_Initialize()外). – 要求main必须带参数运行,否则出错.
• 并行计算粒度大,特别适合于大规模可扩展并行算法
– 由于消息传递程序设计要求用户很好地分解问题,组织不同进程间 的数据交换,并行计算粒度大,特别适合于大规模可扩展并行算法.
• 消息传递是当前并行计算领域的一个非常重要的并行程序 设计方式
2013年8月 MPI并行程序设计 6/217
什么是MPI?
2013年8月
MPI并行程序设计
8/217
为什么要用MPI?
• 高可移植性
– MPI已在IBM PC机上、MS Windows上、所有主要的 Unix工作站上和所有主流的并行机上得到实现。使用 MPI作消息传递的C或Fortran并行程序可不加改变地运 行在IBM PC、MS Windows、Unix工作站、以及各种并 行机上。
11/217
Hello world(C)
#include <stdio.h> #include "mpi.h“
main( int argc, char *argv[] ) { MPI_Init( &argc, &argv ); printf( "Hello, world!\n" ); MPI_Finalize(); }
• [dair@node01 ~]$ mpicc -o hello hello.c • [dair@node01 ~]$ ./hello () [0] Aborting program ! Could not create p4 procgroup. Possible missing fileor program started without mpirun. • [dair@node01 ~]$ mpirun -np 4 hello () Hello World! Hello World! Hello World! 计算机打印字符 Hello World! 我们输入的命令 • [dair@node01 ~]$
MPI并行程序设计
20/217
:开始写MPI并行程序
• MPI 提供了下列函数来回答这些问题:
– 用MPI_Comm_size 获得进程个数 p int MPI_Comm_size(MPI_Comm comm, int *size); – 用MPI_Comm_rank 获得进程的一个叫rank的值,该 rank值为0到p-1间的整数,相当于进程的ID int MPI_Comm_rank(MPI_Comm comm, int *rank);
2013年8月
MPI并行程序设计
13/217
C和Fortran中MPI函数约定
• C
– 必须包含mpi.h. – MPI 函数返回出错代码或 MPI_SUCCESS成功标志. – MPI-前缀,且只有MPI以及MPI_标志后的第一个字母大写,其余 小写.
• Fortran
– 必须包含mpif.h. – 通过子函数形式调用MPI,函数最后一个参数为返回值.
2013年8月 MPI并行程序设计 15/217
MPI结束-MPI_FINALIZE
int MPI_Finalize(void) MPI_FINALIZE(IERROR)
– MPI_FINALIZE是MPI程序的最后一个调用,它结束 MPI程序的运行,它是MPI程序的最后一条可执行语句, 否则程序的运行结果是不可预知的。 – 标志并行代码的结束,结束除主进程外其它进程. – 之后串行代码仍可在主进程(rank = 0)上运行(如果必 须).
%小写o
%np: The number of process.
• mpirun –np 4 a.out • mpirun –np 4 hello
– 4 指定np的实参,表示进程数,由用户指定. – a.out / hello 要运行的MPI并行程序.
2013年8月
MPI并行程序设计
17/217
:运行我们的MPI程序!
• 事实上MPI的所有数据类型均为MPI自定义类型
– 支持异构系统 – 允许消息来自不连续的或类型不一致的存储区(结构,数组散元)
– 集合通信(Collective)
• 数据移动,数据聚集,同步 • 基于point to point 构建
– MPI环境管理函数
• 组,上下文和通信空间/通信子的管理
• 实例
2013年8月 MPI并行程序设计 12/217
Hello world(Fortran)
program main include ‘mpif.h’ integer ierr
call MPI_INIT( ierr ) print *, 'Hello, world!' cawk.baidu.coml MPI_FINALIZE( ierr ) end
2013年8月
MPI并行程序设计
16/217
MPI程序的的编译与运行
• mpif77 hello.f 或 mpicc hello.c
– 默认生成a.out的可执行代码.
• mpif77 –o hello hello.f 或 • mpicc –o hello hello.c
– 生成hello的可执行代码.
2013年8月
MPI并行程序设计
3/217
MPI并行程序设计
Parallel Programming with the Massage Passing Interface (MPI)
2013年8月
MPI并行程序设计
4/217
并行编程标准
• 多线程库标准
– – Win32 API. – – POSIX threads.
• Massage Passing Interface:是消息传递函数库的 标准规范,由MPI论坛开发,支持Fortran和C
– 一种新的库描述,不是一种语言。共有上百个函数调 用接口,在Fortran和C语言中可以直接对这些函数进行 调用 – MPI是一种标准或规范的代表,而不是特指某一个对它 的具体实现 – MPI是一种消息传递编程模型,并成为这种编程模型的 代表和事实上的标准
2013年8月
MPI并行程序设计
7/217
MPI的发展过程
• 发展的两个阶段
– MPI 1.1: 1995
• MPICH:是MPI最流行的非专利实现,由Argonne国家 实验室和密西西比州立大学联合开发,具有更好的可 移植性.
– MPI 1.2~2.0:动态进程, 并行 I/O, 支持F90和 C++(1997).
2013年8月 MPI并行程序设计 18/217
:Hello是如何被执行的?
• SPMD: Single Program Multiple Data(SPMD)
#include "mpi.h" #include <stdio.h> main( int argc, char *argv[] ) { MPI_Init( &argc, &argv ); printf( "Hello, world!\n" ); MPI_Finalize(); } #include "mpi.h" #include <stdio.h> #include "mpi.h" #include <stdio.h> #include "mpi.h" main( #include <stdio.h> #include "mpi.h" int argc,#include <stdio.h> main( charmain( ) int*argv[] argc, { charmain( ) int*argv[] argc, MPI_Init( &argc, &argv ); { char *argv[] ) int argc, printf( "Hello, *argv[] ) ); ); MPI_Init( &argc, &argv { char world!\n" MPI_Finalize(); &argc, &argv ); printf( "Hello, world!\n" ); MPI_Init( { } MPI_Finalize(); &argc, &argv ); printf( "Hello, world!\n" ); MPI_Init( } MPI_Finalize(); world!\n" ); printf( "Hello, } MPI_Finalize(); }
从简单入手!
• 下面我们首先分别以C语言和Fortran语言的 形式给出一个最简单的MPI并行程序Hello (下页). • 该程序在终端打印出Hello World!字样. • “Hello World”:一声来自新生儿的问候.
2013年8月
MPI并行程序设计
• 编译制导标准
– – OpenMP – 可移植共享存储并行编程标准.
• 消息传递库标准
本讨论的重点
– – MPI – – PVM
2013年8月
MPI并行程序设计
5/217
消息传递并行程序设计
• 消息传递并行程序设计
– 指用户必须通过显式地发送和接收消息来实现处理机间的数据交 换。 – 在这种并行编程中,每个并行进程均有自己独立的地址空间,相 互之间访问不能直接进行,必须通过显式的消息传递来实现。 – 这种编程方式是大规模并行处理机(MPP)和机群(Cluster)采 用的主要编程方式。
2013年8月
MPI并行程序设计
2/217
相关网址
• MPI: http://ww.mpi-forum.org, http://www.mcs.anl.gov/mpi • Pthreads: http://www.oreilly.com • PVM: http://www.epm.ornl.gov/pvm/ • OpemMP: http://www.openmp.org • 网上搜索:www.google.com
2013年8月
MPI并行程序设计
9/217
讲座内容提示
• 基本的MPI
– 基本概念 – 点到点通信(Point to point)
• MPI中API的主要内容,为MPI最基本,最重要的内容
– MPI程序的编译和运行
• 深入MPI
– 用户自定义(/派生)数据类型(User-defined(Derived) data type)
::::
Hello World! Hello World! Hello World! Hello World!
19/217
2013年8月
MPI并行程序设计
:开始写MPI并行程序
• 在写MPI程序时,我们常需要知道以下两个 问题的答案:
– 任务由多少个进程来进行并行计算?
– 我是哪一个进程?
2013年8月
– MPI-前缀,且函数名全部为大写.
• MPI函数的参数被标志为以下三种类型:
– IN:参数在例程的调用中不会被修正. – OUT:参数在例程的调用中可能会被修正. – INOUT:参数在一些例程中为IN,而在另一些例程中为OUT.
2013年8月 MPI并行程序设计 14/217
MPI初始化-MPI_INIT
机群应用开发
Parallel Programming: Fundamentals and Implementation
并行编程原理及 程序设计
曙光信息产业有限公司
2013年8月
2013年8月 MPI并行程序设计 1/217
参考文献
• 黄铠,徐志伟著,陆鑫达等译. 可扩展并行计算技术,结构与编程. 北京:机 械工业出版社, P.33~56,P.227~237, 2000. • 陈国良著.并行计算—结构、算法、编程. 北京:高等教育出版社,1999. • Barry Wilkinson and Michael Allen. Parallel Programming(Techniques and Applications using Networked Workstations and Parallel Computers). Prentice Hall, 1999. • 李晓梅,莫则尧等著. 可扩展并行算法的设计与分析. 北京:国防工业出 版社,2000. • 张宝琳,谷同祥等著. 数值并行计算原理与方法. 北京:国防工业出版 社,1999. • 都志辉著. 高性能计算并行编程技术—MPI并行程序设计. 北京:清华大 学出版社, 2001.
int MPI_Init(int *argc, char **argv) MPI_INIT(IERROR)
– MPI_INIT是MPI程序的第一个调用,它完成 MPI程序的所有初始化工作。所有的MPI程序 的第一条可执行语句都是这条语句。 – 启动MPI环境,标志并行代码的开始. – 并行代码之前,第一个mpi函数(除 MPI_Initialize()外). – 要求main必须带参数运行,否则出错.
• 并行计算粒度大,特别适合于大规模可扩展并行算法
– 由于消息传递程序设计要求用户很好地分解问题,组织不同进程间 的数据交换,并行计算粒度大,特别适合于大规模可扩展并行算法.
• 消息传递是当前并行计算领域的一个非常重要的并行程序 设计方式
2013年8月 MPI并行程序设计 6/217
什么是MPI?
2013年8月
MPI并行程序设计
8/217
为什么要用MPI?
• 高可移植性
– MPI已在IBM PC机上、MS Windows上、所有主要的 Unix工作站上和所有主流的并行机上得到实现。使用 MPI作消息传递的C或Fortran并行程序可不加改变地运 行在IBM PC、MS Windows、Unix工作站、以及各种并 行机上。
11/217
Hello world(C)
#include <stdio.h> #include "mpi.h“
main( int argc, char *argv[] ) { MPI_Init( &argc, &argv ); printf( "Hello, world!\n" ); MPI_Finalize(); }
• [dair@node01 ~]$ mpicc -o hello hello.c • [dair@node01 ~]$ ./hello () [0] Aborting program ! Could not create p4 procgroup. Possible missing fileor program started without mpirun. • [dair@node01 ~]$ mpirun -np 4 hello () Hello World! Hello World! Hello World! 计算机打印字符 Hello World! 我们输入的命令 • [dair@node01 ~]$
MPI并行程序设计
20/217
:开始写MPI并行程序
• MPI 提供了下列函数来回答这些问题:
– 用MPI_Comm_size 获得进程个数 p int MPI_Comm_size(MPI_Comm comm, int *size); – 用MPI_Comm_rank 获得进程的一个叫rank的值,该 rank值为0到p-1间的整数,相当于进程的ID int MPI_Comm_rank(MPI_Comm comm, int *rank);
2013年8月
MPI并行程序设计
13/217
C和Fortran中MPI函数约定
• C
– 必须包含mpi.h. – MPI 函数返回出错代码或 MPI_SUCCESS成功标志. – MPI-前缀,且只有MPI以及MPI_标志后的第一个字母大写,其余 小写.
• Fortran
– 必须包含mpif.h. – 通过子函数形式调用MPI,函数最后一个参数为返回值.
2013年8月 MPI并行程序设计 15/217
MPI结束-MPI_FINALIZE
int MPI_Finalize(void) MPI_FINALIZE(IERROR)
– MPI_FINALIZE是MPI程序的最后一个调用,它结束 MPI程序的运行,它是MPI程序的最后一条可执行语句, 否则程序的运行结果是不可预知的。 – 标志并行代码的结束,结束除主进程外其它进程. – 之后串行代码仍可在主进程(rank = 0)上运行(如果必 须).
%小写o
%np: The number of process.
• mpirun –np 4 a.out • mpirun –np 4 hello
– 4 指定np的实参,表示进程数,由用户指定. – a.out / hello 要运行的MPI并行程序.
2013年8月
MPI并行程序设计
17/217
:运行我们的MPI程序!
• 事实上MPI的所有数据类型均为MPI自定义类型
– 支持异构系统 – 允许消息来自不连续的或类型不一致的存储区(结构,数组散元)
– 集合通信(Collective)
• 数据移动,数据聚集,同步 • 基于point to point 构建
– MPI环境管理函数
• 组,上下文和通信空间/通信子的管理
• 实例
2013年8月 MPI并行程序设计 12/217
Hello world(Fortran)
program main include ‘mpif.h’ integer ierr
call MPI_INIT( ierr ) print *, 'Hello, world!' cawk.baidu.coml MPI_FINALIZE( ierr ) end
2013年8月
MPI并行程序设计
16/217
MPI程序的的编译与运行
• mpif77 hello.f 或 mpicc hello.c
– 默认生成a.out的可执行代码.
• mpif77 –o hello hello.f 或 • mpicc –o hello hello.c
– 生成hello的可执行代码.
2013年8月
MPI并行程序设计
3/217
MPI并行程序设计
Parallel Programming with the Massage Passing Interface (MPI)
2013年8月
MPI并行程序设计
4/217
并行编程标准
• 多线程库标准
– – Win32 API. – – POSIX threads.
• Massage Passing Interface:是消息传递函数库的 标准规范,由MPI论坛开发,支持Fortran和C
– 一种新的库描述,不是一种语言。共有上百个函数调 用接口,在Fortran和C语言中可以直接对这些函数进行 调用 – MPI是一种标准或规范的代表,而不是特指某一个对它 的具体实现 – MPI是一种消息传递编程模型,并成为这种编程模型的 代表和事实上的标准
2013年8月
MPI并行程序设计
7/217
MPI的发展过程
• 发展的两个阶段
– MPI 1.1: 1995
• MPICH:是MPI最流行的非专利实现,由Argonne国家 实验室和密西西比州立大学联合开发,具有更好的可 移植性.
– MPI 1.2~2.0:动态进程, 并行 I/O, 支持F90和 C++(1997).
2013年8月 MPI并行程序设计 18/217
:Hello是如何被执行的?
• SPMD: Single Program Multiple Data(SPMD)
#include "mpi.h" #include <stdio.h> main( int argc, char *argv[] ) { MPI_Init( &argc, &argv ); printf( "Hello, world!\n" ); MPI_Finalize(); } #include "mpi.h" #include <stdio.h> #include "mpi.h" #include <stdio.h> #include "mpi.h" main( #include <stdio.h> #include "mpi.h" int argc,#include <stdio.h> main( charmain( ) int*argv[] argc, { charmain( ) int*argv[] argc, MPI_Init( &argc, &argv ); { char *argv[] ) int argc, printf( "Hello, *argv[] ) ); ); MPI_Init( &argc, &argv { char world!\n" MPI_Finalize(); &argc, &argv ); printf( "Hello, world!\n" ); MPI_Init( { } MPI_Finalize(); &argc, &argv ); printf( "Hello, world!\n" ); MPI_Init( } MPI_Finalize(); world!\n" ); printf( "Hello, } MPI_Finalize(); }