520 likes | 757 Views
第 2 讲 并行计算框架及案例. 主讲人:安俊秀(教授) anjunxiu@cuit.edu.cn 并行计算实验室(成都). 并行计算产生背景. 各个并行执行部分. 整个大的串行任务. 分解. 根据大任务内在相关性. 需做大量运算,持续时间长. 各个相对独立模块部分并行执行,节约运算时间. 并行计算产生背景. 各个并行执行部分. 整个大的串行任务. 分解. 根据大任务内在相关性. 需做大量运算,持续时间长. 各个相对独立模块部分并行执行,节约运算时间. 并行计算是相对于串行计算. 并行计算是相对于串行计算. 并行计算概念. 并行计算概念.
E N D
第2讲 并行计算框架及案例 主讲人:安俊秀(教授) anjunxiu@cuit.edu.cn 并行计算实验室(成都)
并行计算产生背景 各个并行执行部分 整个大的串行任务 分解 根据大任务内在相关性 需做大量运算,持续时间长 各个相对独立模块部分并行执行,节约运算时间
并行计算产生背景 各个并行执行部分 整个大的串行任务 分解 根据大任务内在相关性 需做大量运算,持续时间长 各个相对独立模块部分并行执行,节约运算时间
并行的层次 粗 • 程序级并行 • 子程序级并行 • 语句级并行 • 操作级并行 • 微操作级并行 并行粒度 细 高性能计算、高端计算、超级计算
并行的层次 粗 • 程序级并行 • 子程序级并行 • 语句级并行 • 操作级并行 • 微操作级并行 并行粒度 细 高性能计算、高端计算、超级计算
并行计算基本条件 • 硬件(并行机) • 组成要素:节点,互联网络,内存 • 结构模型:PVP, SMP, DSM, MPP, COW • 并行算法设计(略) • 并行编程环境 • 系统环境:常见主流Unix/Linux操作系统 • 编程语言:Fortran 77/90/9,C/C++
并行计算基本条件 • 硬件(并行机) • 组成要素:节点,互联网络,内存 • 结构模型:PVP, SMP, DSM, MPP, COW • 并行算法设计(略) • 并行编程环境 • 系统环境:常见主流Unix/Linux操作系统 • 编程语言:Fortran 77/90/9,C/C++
并行计算机的分类 并行计算科学中主要研究的是空间上的并行问题。 空间上的并行导致了两类并行机的产生,按照Flynn的说法分为:单指令流多数据流(SIMD)和多指令流多数据流(MIMD)。我们常用的串行机也叫做单指令流单数据流(SISD)。 SISD MIMD SIMD
并行计算机的分类 并行计算科学中主要研究的是空间上的并行问题。 空间上的并行导致了两类并行机的产生,按照Flynn的说法分为:单指令流多数据流(SIMD)和多指令流多数据流(MIMD)。我们常用的串行机也叫做单指令流单数据流(SISD)。 SISD MIMD SIMD
1 并行计算框架 • PVP( Parallel Vector Processor,并行向量处理机) • 代表: • 银河I • NEC地球模拟器
1 并行计算框架 • PVP( Parallel Vector Processor,并行向量处理机) • 代表: • 银河I • NEC地球模拟器
2 并行计算框架 • SMP( Symmetric Multiprocessor,对称多处理机) • 单一操作系统管理,共享内存及计算机的其他资源. • 代表: • 曙光1号 • IBM RS/6000
2 并行计算框架 • SMP( Symmetric Multiprocessor,对称多处理机) • 单一操作系统管理,共享内存及计算机的其他资源. • 代表: • 曙光1号 • IBM RS/6000
3 并行计算框架 • DSM( Distributed Shared Memory,分布式共享存储) • 单一的操作系统, • 共享内存 • 代表: • SGI的Origin3000 • Altix3000系列 • SUN的Fire15K
3 并行计算框架 • DSM( Distributed Shared Memory,分布式共享存储) • 单一的操作系统, • 共享内存 • 代表: • SGI的Origin3000 • Altix3000系列 • SUN的Fire15K
并行计算框架 4 • MPP(Massively Parallel Processor,大规模并行处理机) • 每个结点均有自己的 • 操作系统,独立的内存. • 代表: • Intel Option Red • IBM SP2 • Dawning 1000
并行计算框架 4 • MPP(Massively Parallel Processor,大规模并行处理机) • 每个结点均有自己的 • 操作系统,独立的内存. • 代表: • Intel Option Red • IBM SP2 • Dawning 1000
5 并行计算框架 • COW(Cluster of Workstation,集群工作站) • 代表: • IBM Cluster 1350/1600 • 曙光2000, 3000 • 目前分布式计算、云计算体系 的原型
5 并行计算框架 • COW(Cluster of Workstation,集群工作站) • 代表: • IBM Cluster 1350/1600 • 曙光2000, 3000 • 目前分布式计算、云计算体系 的原型
MPI产生背景 并行语言的实现方式和实现难度的关系图 • 并行程序设计方式: • 设计全新的并行语言 • 扩展串行语言语法,使其支持并行特征 • 为串行语言提供可调用的并行库 • MPI(Message Passing Interface,消息传递接口):是消息传递函数库的标准规范,采用提供并行库的方式 实现难度 提供并行库 扩充语法成分 新语言 改动多少
一个简单的MPI程序 —Hello.c #include “mpi.h” /* 导入包含有MPI库函数的头文件*/ #include <stdio.h>/* 导入C语言头文件 */ /** * 使用C语言作为宿主语言,调用MPI库编写简单Hello.c并行程序 */ int main(int argc, char *argv[]) { MPI_init(&argc, &argv);/* MPI库函数 */ printf(“hello parallel world!\n”); /* C库函数 */ MPI_Finalize(); /* MPI库函数 */ return 0; } MPI_Init(…); … 并行代码; … MPI_Fainalize(); 只能有串行代码;
一个简单的MPI程序 —Hello.c #include “mpi.h” /* 导入包含有MPI库函数的头文件*/ #include <stdio.h>/* 导入C语言头文件 */ /** * 使用C语言作为宿主语言,调用MPI库编写简单Hello.c并行程序 */ int main(int argc, char *argv[]) { MPI_init(&argc, &argv);/* MPI库函数 */ printf(“hello parallel world!\n”); /* C库函数 */ MPI_Finalize(); /* MPI库函数 */ return 0; } MPI_Init(…); … 并行代码; … MPI_Fainalize(); 只能有串行代码;
一个简单的MPI程序 —Hello.c 运行: • 启动机器集群中的3个机器节点: • 编译Hello.c程序: • 执行Hello程序: 注意:可执行程序Hello.o必须同时位于3个机器节点的test3目录下。
一个简单的MPI程序 —Hello.c 运行: • 启动机器集群中的3个机器节点: • 编译Hello.c程序: • 执行Hello程序: 注意:可执行程序Hello.o必须同时位于3个机器节点的test3目录下。
MPI消息 • 消息(message):MPI程序中在进程间通信所传送的所有信息称为消息。 • 作用: • 控制整个集群内的所有机器节点进行协同工作 • 对底层异构系统进行抽象,实现程序可移植性 • 组成: • 消息信封 • 消息内容
MPI消息 • 消息(message):MPI程序中在进程间通信所传送的所有信息称为消息。 • 作用: • 控制整个集群内的所有机器节点进行协同工作 • 对底层异构系统进行抽象,实现程序可移植性 • 组成: • 消息信封 • 消息内容
MPI消息传递过程 • 分三个阶段: • 消息装配 • 消息发送 • 消息拆卸 数据接收缓冲区 数据发送缓冲区 消息装配 消息拆卸 消息传递 MPI消息传递过程
MPI消息传递过程 • 分三个阶段: • 消息装配 • 消息发送 • 消息拆卸 数据接收缓冲区 数据发送缓冲区 消息装配 消息拆卸 消息传递 MPI消息传递过程
MPI常用六个基本函数 • MPI_Init(…); • MPI_Comm_size(…); • MPI_Comm_rank(…); • MPI_Send(…); • MPI_Recv(…); • MPI_Finalize();
int MPI_Init(int *argc, char **argv) • 启动MPI环境,标志并行代码的开始. • 并行代码之前,第一个mpi函数(除MPI_Initialize()外). • 接收main函数传递的参数. • int MPI_Finalize(void) • 标志并行代码的结束,结束除主进程外其它进程.
int MPI_Comm_size ( MPI_Comm comm, int *size ) • 获得通信空间comm中规定的组包含的进程的数量. • int MPI_Comm_rank ( MPI_Comm comm, int *rank ) • 得到本进程在通信空间comm中的rank值,即在组中的逻辑编号(从0开始,类似于进程ID).
int MPI_Send( void *buff, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) • 标准阻塞发送消息 • buff:消息发送缓冲区 • count: 指定数据类型MPI_Datatype的消息个数, 而不是字节数. • dest: 发送消息的目的地 • tag: 消息标签 • comm: 通信空间或通信域
int MPI_Recv( void *buff, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status) • 标准阻塞接收消息 • buff:消息接收缓冲区 • count: 指定数据类型MPI_Datatype的消息个数, 而不是字节数. • source: 发送消息源 • tag: 消息标签 • comm: 通信空间或通信域 • status:记录消息接收状态(成功或失败)
简单消息发送与接收案例—HelloWord.c #include “mpi.h” main(int argc, char* argv[]) { int p; /*进程数,该变量为各处理器中的同名变量 */ intmy_rank; /*我的进程ID,存储也是分布的 */ MPI_Status status; /*消息接收状态变量,存储也是分布 */ charmessage[100]; /*消息buffer,存储也是分布的 */ MPI_Init(&argc, &argv); /*初始化MPI*/ /*该函数被各进程各调用一次,得到自己的进程rank值*/ MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); /*该函数被各进程各调用一次,得到进程数*/ MPI_Comm_size(MPI_COMM_WORLD, &p);
简单消息发送与接收案例—HelloWord.c #include “mpi.h” main(int argc, char* argv[]) { int p; /*进程数,该变量为各处理器中的同名变量 */ intmy_rank; /*我的进程ID,存储也是分布的 */ MPI_Status status; /*消息接收状态变量,存储也是分布 */ charmessage[100]; /*消息buffer,存储也是分布的 */ MPI_Init(&argc, &argv); /*初始化MPI*/ /*该函数被各进程各调用一次,得到自己的进程rank值*/ MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); /*该函数被各进程各调用一次,得到进程数*/ MPI_Comm_size(MPI_COMM_WORLD, &p);
简单消息发送与接收案例—HelloWord.c if (my_rank != 0) { /*建立消息*/ sprintf(message, “Hello Word, I am %d!",my_rank); /* 发送长度取strlen(message)+1,使\0也一同发送出去*/ MPI_Send(message,strlen(message)+1, MPI_CHAR, 0,99, MPI_COMM_WORLD); } else{ /* my_rank == 0 */ for (source = 1; source <= 2; source++) {/* 指定3个进程的并行环境*/ MPI_Recv(message, 100, MPI_CHAR, source, 99, MPI_COMM_WORLD, &status); printf(“%s\n", message); } } MPI_Finalize(); /*关闭MPI,标志并行代码段的结束*/ } /* main */
简单消息发送与接收案例—HelloWord.c if (my_rank != 0) { /*建立消息*/ sprintf(message, “Hello Word, I am %d!",my_rank); /* 发送长度取strlen(message)+1,使\0也一同发送出去*/ MPI_Send(message,strlen(message)+1, MPI_CHAR, 0,99, MPI_COMM_WORLD); } else{ /* my_rank == 0 */ for (source = 1; source <= 2; source++) {/* 指定3个进程的并行环境*/ MPI_Recv(message, 100, MPI_CHAR, source, 99, MPI_COMM_WORLD, &status); printf(“%s\n", message); } } MPI_Finalize(); /*关闭MPI,标志并行代码段的结束*/ } /* main */
HelloWord.c的编译与运行 • mpicc HelloWord.c • 默认生成a.out的可执行代码. • mpicc –o HelloWord HelloWord.c • 生成HelloWorld的可执行代码. • mpirun –n 3 ./a.out 或 • mpirun –n 3 ./HelloWord • 3:指定执行该并行程序的机器节点数,由用户指定. • a.out / HellowWord: 要运行的MPI并行程序.
HelloWord.c的编译与运行 • mpicc HelloWord.c • 默认生成a.out的可执行代码. • mpicc –o HelloWord HelloWord.c • 生成HelloWorld的可执行代码. • mpirun –n 3 ./a.out 或 • mpirun –n 3 ./HelloWord • 3:指定执行该并行程序的机器节点数,由用户指定. • a.out / HellowWord: 要运行的MPI并行程序.
案例执行过程 串行程序 MPI_Init() MPI_Comm_rank() MPI_Comm_rank() MPI_Comm_rank() 进程2 进程0 进程1 进程0接收进程1的消息 . . Send(); . . . Send(); . . . Recv(); . Recv(); . 进程0接收进程2的消息 HelloWord, I am 1 HelloWord, I am 2 MPI_Finalize() 串行程序
案例执行过程 串行程序 MPI_Init() MPI_Comm_rank() MPI_Comm_rank() MPI_Comm_rank() 进程2 进程0 进程1 进程0接收进程1的消息 . . Send(); . . . Send(); . . . Recv(); . Recv(); . 进程0接收进程2的消息 HelloWord, I am 1 HelloWord, I am 2 MPI_Finalize() 串行程序
案例程序解析 • 上述案例程序以C语言为宿主语言,结合MPI提供的并行库,实现3个机器节点执行该MPI程序的功能。 • 上述程序在0号机器节点上打印输出: HelloWord, I am 1 HelloWord, I am 2 • MPI并行程序约定: • 程序开头必须包含mpi.h. • MPI函数返回出错代码或 MPI_SUCCESS成功标志. • MPI_ 前缀,且只有MPI名称以及MPI_标志后的第一个字母大写,其余小写. • 程序的并行部分以MPI_Init()开头,以MPI_Finalize()结束,其它部分为程序的串行部分.
案例程序解析 • 上述案例程序以C语言为宿主语言,结合MPI提供的并行库,实现3个机器节点执行该MPI程序的功能。 • 上述程序在0号机器节点上打印输出: HelloWord, I am 1 HelloWord, I am 2 • MPI并行程序约定: • 程序开头必须包含mpi.h. • MPI函数返回出错代码或 MPI_SUCCESS成功标志. • MPI_ 前缀,且只有MPI名称以及MPI_标志后的第一个字母大写,其余小写. • 程序的并行部分以MPI_Init()开头,以MPI_Finalize()结束,其它部分为程序的串行部分.
参考文献 • 参考资料 主要的MPI主页及MPI标准http://www.mpi-forum.orgMPIF主页http://www.mcs.anl.gov/mpiMPI主页http://www.netlib.org/mpi/index.htmlnetlib上的MPI站点http://www-unix.mcs.anl.gov/mpi/mpich/ANL/MSU实现的MPICHhttp://www-unix.mcs.anl.gov/mpi/tutorial/MPI相关材料http://www.mcs.anl.gov/mpi/usingmpiMPI教程http://www.mcs.anl.gov/mpi/usingmpi2MPI教程 • 都志辉著. 高性能计算并行编程技术—MPI并行程序设计. 北京:清华大学出版社, 2001.