并行程序设计
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
::::
Hello World! Hello World! Hello World! Hello World!
MPI并行程序设计
:开始写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);
#include <stdio.h> #include "mpi.h" main(int argc, char* argv[]) { int numprocs, myid, source; MPI_Status status; char message[100];
MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &myid); MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
#include <stdio.h> #include "mpi.h“
main( int argc, char *argv[] ) { MPI_Init( &argc, &argv ); printf( "Hello, world!\n" ); MPI_Finalize(); }
2016年12月 MPI并行程序设计
2016年12月
MPI并行程序设计
if (myid != 0) /* 若是非 0 进程*/ { /* 先将字符串拷 贝到发送到缓冲区message中然后调用MPI_Send语句将它 发出用 strlen(message)指定消息的长度用MPI_CHAR指定 消息的数据类型 0 指明发往进程0 使 用的消息标识是99 MPI_COMM_WORLD是包含本进程 进程0 和接收消息的进 程进程0 的通信域 发送方和接收方必须在同一个通信域 中 由通信域来统一协调和控制消息 的发送和接收*/
MPI并行程序设计
解剖greetings程序
• 头文件: mpi.h/mpif.h. • int MPI_Init(int *argc, char *argv)
• 启动MPI环境,标志并行代码的开始. • 并行代码之前,第一个mpi函数(除MPI_Initialize()外). • 要求main必须带参数运行,否则出错.
2016年12月
MPI并行程序设计
6/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 #include <stdio.h> "mpi.h" #include #include <stdio.h> "mpi.h" main( #include #include <stdio.h> "mpi.h" intmain( argc, #include <stdio.h> char intmain( *argv[] argc, ) { char intmain( *argv[] argc, ) MPI_Init( { char int &argc, *argv[] argc,&argv ) ); printf( MPI_Init( { "Hello, char &argc, world!\n" *argv[] &argv ) ); ); MPI_Finalize(); printf( MPI_Init( { "Hello,&argc, world!\n" &argv ); ); } MPI_Finalize(); printf( MPI_Init( "Hello,&argc, world!\n" &argv ); ); } MPI_Finalize(); printf( "Hello, world!\n" ); } MPI_Finalize(); }
2016年12月
MPI并行程序设计
8/217
• 并行可分为两种,一种是任务并行(parfor),另 一种则数据并行(Spmd)。Spmd中的“Single program”方面指的是同一段代码运行在不同的多 个机器上。你在一个机器上运行一个程序,被标志 为spmd模块的其他部分运行在其他机器上。当这 些块运行完毕后,你的程序继续在客户端运行。 “Multiple data”方面指的是虽然spmd语句在所有 的机器上运行相同的代码。
2016年12月
MPI并行程序设计
分析greetings
#include <stdio.h> #include "mpi.h“ main(int argc, char* argv[]) { int numprocs; /*进程数,该变量为各处理器中的同名变量, 存储是分布的 int myid; /*我的进程ID,存储也是分布的 MPI_Status status; /*消息接收状态变量,存储也是分布的 */ char message[100]; /*消息buffer,存储也是分布的 */ /*初始化MPI*/ MPI_Init(&argc, &argv); /*该函数被各进程各调用一次,得到自己的进程rank值*/ MPI_Comm_rank(MPI_COMM_WORLD, &myid); /*该函数被各进程各调用一次,得到进程数*/ MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
• 一种新的库描述,不是一种语言。共有上百个函数调用接口,在Fortran 和C语言中可以直接对这些函数进行调用 • MPI是一种标准或规范的代表,而不是特指某一个对它的具体实现 • MPI是一种消息传递编程模型,并成为这种编程模型的代表和事实上的标 准
2016年12月
MPI并行程序设计
Hello world(C)
MPI并行程序设计
有消息传递 Greeting
进程 0 rank=0 . . Recv() . . . 进程 1 rank=1 . . Send() . . . 进程 2 rank=2 . . Send() . . . 进程 3 rank=3 . . Send() . . .
MPI并行程序设计
greetings(c)
数据传送 + 同步操作
Process 1 Data 发送请求
Data Data Data Data Data Data Data Data
Process 0
Yes
Time
2016年12月
需要发送方与接收方合作完成.
MPI并行程序设计
MPI消息
• MPI消息包括信封和数据两个部分,信封指出了发送或接收消息 的对象及相关信息,而数据是本消息将要传递的内容 • 数据:<起始地址、数据个数、数据类型> • 信封:<源/目的、标识、通信域>
A M 进程P
B 进程Q
A M T
用户缓冲区
A M 进程P
2016年12月
S
B 进程Q 用户指定缓冲区
17/217
B 进程Q
进程P
系统缓冲区
MPI并行程序设计
消息传送
MPI_Send(A, 10, MPI_DOUBLE, 1,99, MPI_COMM_WORLD);
MPI_Recv(B, 20, MPI_DOBULE, 0, 99, MPI_COMM_WORLD, &status);
MPI入门介绍
2016年12月
MPI并行程序设计
——led
消息传递并行程序设计
• 消息传递并行程序设计
• 指用户必须通过显式地发送和接收消息来实现处理机间的数据交换。 • 在这种并行编程中,每个并行进程均有自己独立的地址空间,相互之间访问不能直接 进行,必须通过显式的消息传递来实现。 • 这种编程方式是大规模并行处理机(MPP)和机群(Cluster)采用的主要编程方式。
:开始写MPI并行程序
• 在写MPI程序时,我们常需要知道以下两个问题的答案:
• 任务由多少个进程来进行并行计算? • 我是哪一个进程?
2016年12月
MPI并行程序设计
5/217
更新的Hello World(c)
#include <stdio.h> #include "mpi.h" main( int argc, char *argv[] ) { int myid, numprocs; MPI_Init( &argc, &argv ); MPI_Comm_rank( MPI_COMM_WORLD, &myid ); MPI_Comm_size( MPI_COMM_WORLD, &numprocs ); printf(“I am %d of %d\n", myid, numprocs ); MPI_Finalize(); }
• 通信子(通信空间): MPI_COMM_WORLD:
• 一个通信空间是一个进程组和一个上下文的组合.上下文可看作为 组的超级标签,用于区分不同的通信子. • 在执行函数MPI_Init之后,一个MPI程序的所有进程形成一个缺省的 组,这个组的通信子即被写作MPI_COMM_WORLD. • 该参数是MPI通信操作函数中必不可少的参数,用于限定参加通信的 进程的范围.
MPI并行程序设计
解剖greetings程序
• int MPI_Comm_size ( MPI_Comm comm, int *size )
• 获得通信空间comm中规定的组包含的进程的数量. • 指定一个communicator,也指定了一组共享该空间的进程, 这些进程组成该communicator 的group.
• 进程0直接执行接收消息的操作 这里它使用message作为 接收缓冲区 由此可见 对于同 一个变量 在发送进程和接 收进程中的作用是不同的 它指定接收消息的最大长度为 100 消 息的数据类型为MPI_CHAR字符型 接收的消息来自 进程0 而接收消息携带的标识必须为 99 ,使用的通信域 也是MPI_COMM_WORLD ,接收完成后的各种状态信息 存放在status中 接收完成后 它直接将接收到的字符串打 印在屏幕上 */
• 并行计算粒度大,特别适合于大规模可扩展并行算法
• 由于消息传递程序设计要求用户很好地分解问题,组织不同进程间的数据交换,并行计算 粒度大,特别适合于大规模可扩展并行算法.
• 消息传递是当前并行计算领域的一个非常重要的并行程序设计方式
2016年12月
MPI并行程序设计
什么是MPI?
• Massage Passing Interface:是消息传递函数库的标准规范,由MPI 论坛开发,支持Fortran和C
MPI并行程序设计
有消息传递greetings(c)
if (myid != 0) { strcpy(message, "Hello World!"); MPI_Send(message,strlen(message)+1, MPI_CHAR, 0,99, MPI_COMM_WORLD); } else {/* myid == 0 */ for (source = 1; source < numprocs; source++) { MPI_Recv(message, 100, MPI_CHAR, source, 99, MPI_COMM_WORLD, &status); printf("%s\n", message); } } MPI_Finalize(); } /* end main */
• int MPI_Comm_rank ( MPI_Comm comm, int *rank )
• 得到本进程在通信空间中的rank值,即在组中的逻辑编号(从0开始).
• int MPI_Finalize()
• 标志并行代码的结束,结束除主进程外其它进程. • 之后串行代码仍可在主进程(rank = 0)上运行(如果必须).
2016年12月
MPI并行程序设计
什么是缓冲区?
1. 应用程序中说明的变量,在消息传递语句中又用作缓冲区的起始位置. 2. 也可表示由系统(不同用户)创建和管理的某一存储区域,在消息传递过 程中用于暂存放消息.也被称为系统缓冲区. 3. 用户可设置一定大小的存储区域,用作中间缓冲区以保留可能出现在 其应用程序中的任意消息.