前言 此书是在李三立院士的直接支持和指导下完成的。根据我们多年来在并行计算研究领域 的实践发现,并行计算已经从原来的阳春白雪、曲高和宴的局面载来戴卷诱并普及到各个领 域和方面,并行计算的硬件支持也从原来只有国家或大公司才能负担的超级计算机发展到现 在一个小的实验室就可以组建的“个人超级计算机”网络工作站或风 并行计算无 种强大的计算工具,但是,真正需要并行计算的非计算机专业人员却缺乏这方面的指导,他 们迫切需要一本较为通俗的、可以较快理解并掌握并行计算这一工具的参考书,而不是过多 侧重并行计算自身理论的专业著作。这是促使本书问世的主要原因。 MPI是目前最重要的并行编程工具,它具有移植性好、功能强大、效率高等多种优点 而且有多种不同的免费、高效、实用的实现版 几乎所有的并行计算机厂商都提供对它的 支持,这是其它所有的并行编程环境都无法比拟的。MP于1994年产生,虽然产生时间相对 较晚,由于它吸收了其它多种并行环境的优点,同时兼顾性能、功能、移植性等特点,在短 短的几年内便迅速普及,成为消息传递并行编程模式的标准,这也从一个方面说明了MPI的 生命力和优越性。 MPI其实就是一个“库”,共有上百个函数调用接D,在FORTRAN7和C语言中可以直 接对这些函数进行调用。MPI提供的调用虽然很多 但最常使用的只有6个 只要会使用 FORTRAN 7刀或者是C,就可以比较容易地掌握MPI的基本功能,只需通过使用这6个函数就 可以完成几乎所有的通信功能。由于Fortran90和C+的使用也十分广泛,MPI后来又进 步提供对Fon90和C++的调用接口,这更提高的MPI的话用性。 根据我们的经验,只要掌握了FORTRAN77和C的程序员,哪怕一开始对MPI并行程序设 计 无所知, 只要通过 定的培训和练习 是可以很 P的基本功能并通过使用它米 制并行程序的,但是要全面掌握M叫,必须通过大量的练习并需要更长的时间。鉴于此, 本书的编写也是按照从易到难、从简单到复杂、从低级到高级的顺序进行的。书中第一部分 简单介绍了并行程序设计的基本知识;然后在第二部分介绍基本的MP并行程序设计方法, 它虽然基本,但是却非常重要,因为通过这部分介绍的功能,可以实现几平所有的通信功能 第三部分是在第二部分的 基础上,介绍高级、复杂的MPI并行程序设计, 使用高级的MP 用可以提高并行程序的通用性和移植性,对提高并行程序的开发效率、可读性以及并行程序 的执行效率等都有好处;最后一部分介绍MPI的最新扩展MP-2,若重对动态进程管理、远 程存储访问和并行VO进行了讲解。 据我们所知,日前国内还没有一本专门介绍P并行程序设计的著作,希望本书的问田 能够对那些迫切需要这方面参考资料的读者有所帮助,希望本书对促进并行计算在我国的推 一和普及作出贡献 在本书的筹划过程中,清华大学出版社的李幼哲老师根据他多年从事计算机类图书出形 的经验,对我进行了指导并提出了大量的建设性意见,我感谢他!本教研组的老师和同学也 对本书提出了许多宝贵的建议,我感谢他们! 希望读者在阅读此书时,将发现的错误或您的建议告诉我,以便在再版时进一步提高本 书的质量,本人将非常感谢 作者 2001年2月1日于清华大学
XI 前言 此书是在李三立院士的直接支持和指导下完成的 根据我们多年来在并行计算研究领域 的实践发现 并行计算已经从原来的阳春白雪 曲高和寡的局面越来越渗透并普及到各个领 域和方面 并行计算的硬件支持也从原来只有国家或大公司才能负担的超级计算机发展到现 在一个小的实验室就可以组建的 个人超级计算机 --网络工作站或网络PC 并行计算是一 种强大的计算工具 但是 真正需要并行计算的非计算机专业人员却缺乏这方面的指导 他 们迫切需要一本较为通俗的 可以较快理解并掌握并行计算这一工具的参考书 而不是过多 侧重并行计算自身理论的专业著作 这是促使本书问世的主要原因 MPI是目前最重要的并行编程工具 它具有移植性好 功能强大 效率高等多种优点 而且有多种不同的免费 高效 实用的实现版本 几乎所有的并行计算机厂商都提供对它的 支持 这是其它所有的并行编程环境都无法比拟的 MPI于1994年产生 虽然产生时间相对 较晚 由于它吸收了其它多种并行环境的优点 同时兼顾性能 功能 移植性等特点 在短 短的几年内便迅速普及 成为消息传递并行编程模式的标准 这也从一个方面说明了MPI的 生命力和优越性 MPI其实就是一个 库 共有上百个函数调用接口 在FORTRAN 77和C语言中可以直 接对这些函数进行调用 MPI提供的调用虽然很多 但最常使用的只有6个 只要会使用 FORTRAN 77或者是C 就可以比较容易地掌握MPI的基本功能 只需通过使用这6个函数就 可以完成几乎所有的通信功能 由于Fortran90 和C++的使用也十分广泛 MPI后来又进一 步提供对Fortran 90和C++的调用接口 这更提高的MPI的适用性 根据我们的经验 只要掌握了FORTRAN77和C的程序员 哪怕一开始对MPI并行程序设 计一无所知 只要通过一定的培训和练习 是可以很快掌握MPI的基本功能并通过使用它来 编制并行程序的 但是要全面掌握MPI 必须通过大量的练习并需要更长的时间 鉴于此 本书的编写也是按照从易到难 从简单到复杂 从低级到高级的顺序进行的 书中第一部分 简单介绍了并行程序设计的基本知识 然后在第二部分介绍基本的MPI并行程序设计方法 它虽然基本 但是却非常重要 因为通过这部分介绍的功能 可以实现几乎所有的通信功能 第三部分是在第二部分的基础上 介绍高级 复杂的MPI并行程序设计 使用高级的MPI调 用可以提高并行程序的通用性和移植性 对提高并行程序的开发效率 可读性以及并行程序 的执行效率等都有好处 最后一部分介绍MPI的最新扩展MPI-2 着重对动态进程管理 远 程存储访问和并行I/O进行了讲解 据我们所知 目前国内还没有一本专门介绍MPI并行程序设计的著作 希望本书的问世 能够对那些迫切需要这方面参考资料的读者有所帮助 希望本书对促进并行计算在我国的推 广和普及作出贡献 在本书的筹划过程中 清华大学出版社的李幼哲老师根据他多年从事计算机类图书出版 的经验 对我进行了指导并提出了大量的建设性意见 我感谢他 本教研组的老师和同学也 对本书提出了许多宝贵的建议 我感谢他们 希望读者在阅读此书时 将发现的错误或您的建议告诉我 以便在再版时进一步提高本 书的质量 本人将非常感谢 作者 2001年2月1日于清华大学
程序列表 程序1第一个FORTRAN77+MPI程序 17 程序3第一个C+P1并行程序 20 程序4第一个Fortran90+MP程 程序了简单的发 接收程序 29 程序6正确的类型匹配PI REAL对应于PI REAL) 3 程序7不正确的类型匹配PIRE4L和P1BYTE不匹配) 31 程序8正确的无类型数据匹配PI BYTE和MPI BYTE对应) 32 程序9 PI CHARACTER数提类型 33 程序10对特定的部分进行计时 36 程序11MP时间函数的测试 程序12获取当前机器名和P1版本号 .39 程序13P1主动退出秋行的例子 41 程序14数据在进程间的接力传送 程序5任意进程间相互问候 程序16接收任意源和任意标识的消息 49 程序17总会死锁的发送接收序列 .47 程序18不安全的发送接收序列 .48 程序19安全的发送接收序列 程序20串行表示的acohi迭代 程序2I用MPI SEND和MPI RECVS实现的Jacobi送代 程序22用MPI SENDRECVS实现的Jacob话代 程序23用虚拟进程实现的acobi达代. .62 程序24矩库向量乘 65 程序25主进程按续与乱续打印从进程的消息 67 程序26使用缓存通信模式发送消息 程序27同步模式的消息发 16 程序28就绪通信模式的例子 .79 程序29消息接收次序示例 97 程序30非阻塞操作和PI WAIT简单的使用方法 103 程字3非阳塞信的取消 10s 程序2使用MPL REQUE区 FREE的 个例子 程序33使用阻塞检查等待接收消息 . 程序34错误的消息接收方式, .112 程序35非阻塞通信的语义约束。 113 程序36非阴塞通信实现的Ua00bi洪代 116 程序37用重复非阻塞通信实现Jacobi送代 23 程序8 广播程序示例 12 程序39 PI Gather使用示例 129 程序0 MPI_Gatherv使用示例. 130 程序41 IPI Scatter应用示例 .132 七
XII 程序列表 程序 1 第一个FORTRAN77+MPI程序 .....................................................................................................17 程序 3 第一个C+MPI并行程序.................................................................................................................20 程序 4 第一个Fortran90+MPI 程序 ........................................................................................................20 程序 5 简单的发送接收程序 .....................................................................................................................29 程序 6 正确的类型匹配 MPI_REAL对应于MPI_REAL ..................................................................31 程序 7 不正确的类型匹配 MPI_REAL和MPI_BYTE不匹配 ..........................................................31 程序 8 正确的无类型数据匹配 MPI_BYTE和MPI_BYTE对应 ......................................................32 程序 9 MPI_CHARACTER数据类型.......................................................................................................32 程序 10 对特定的部分进行计时...............................................................................................................36 程序 11 MPI时间函数的测试......................................................................................................................38 程序 12 获取当前机器名和MPI版本号 ...................................................................................................39 程序 13 MPI主动退出执行的例子..........................................................................................................41 程序 14 数据在进程间的接力传送...........................................................................................................42 程序 15 任意进程间相互问候...................................................................................................................45 程序 16 接收任意源和任意标识的消息...................................................................................................46 程序 17 总会死锁的发送接收序列...........................................................................................................47 程序 18 不安全的发送接收序列...............................................................................................................48 程序 19 安全的发送接收序列...................................................................................................................49 程序 20 串行表示的Jacobi迭代 ..............................................................................................................52 程序 21 用MPI_SEND和MPI_RECV实现的Jacobi迭代.........................................................................55 程序 22 用MPI_SENDRECV实现的Jacobi迭代 ......................................................................................60 程序 23 用虚拟进程实现的Jacobi迭代....................................................................................................62 程序 24 矩阵向量乘....................................................................................................................................65 程序 25 主进程按续与乱续打印从进程的消息......................................................................................67 程序 26 使用缓存通信模式发送消息.......................................................................................................74 程序 27 同步模式的消息发送...................................................................................................................76 程序 28 就绪通信模式的例子...................................................................................................................79 程序 29 消息接收次序示例.......................................................................................................................97 程序 30 非阻塞操作和MPI_WAIT简单的使用方法..............................................................................103 程序 31 非阻塞通信的取消 ...................................................................................................................108 程序 32 使用MPI_REQUEST_FREE的一个例子..................................................................................110 程序 33 使用阻塞检查等待接收消息..................................................................................................... 111 程序 34 错误的消息接收方式.................................................................................................................112 程序 35 非阻塞通信的语义约束.............................................................................................................113 程序 36 非阻塞通信实现的Jacobi迭代..................................................................................................116 程序 37 用重复非阻塞通信实现Jacobi迭代..........................................................................................122 程序 38 广播程序示例............................................................................................................................127 程序 39 MPI_Gather使用示例..................................................................................................................129 程序 40 MPI_Gatherv使用示例................................................................................................................130 程序 41 MPI_Scatter应用示例...............................................................................................................132
程序42P1 Scattery应用示例. 132 程序BMPL_Allgather应用示例 13 程序 MPI_Allgatherv应用示 程序45 MPI AlltoaⅡ使用示例. .13 程序46同步示例 139 阴字7求一值 144 程序48错误的广播调用次序 1s0 程序49错误的广插和点到点阻塞通信调用次序 15d 程序0结果不确定的调用 程序5I归约操作PI MAXLOC示例 程序52用户自定义的归约操作 155 程序53新数据类型的递交与释放 165 程序54单的机PI ADDRE调用示例 171 程序55包含多种 同类型的新MPI数据类型的定义 程序56接收数据个数的获取 174 程序57下三角矩阵数据类型的定义和使用 .176 程序58矩阵转置数据类型的定义.」 17 程序59相同类型数据的打包和解包 17g 程序60不同类型数据的打包与解包 18 程序61 个完成的打包解包例于 程序62创建进程组和通信域的简单示例」 .190 程序63通信域的分裂与组间通信域的生成 194 程序64属性的简单使用方法 195 程序的在具有虚拟拓扑的进程组上进行数据传递 205 程序6用虚拟进程拓扑和向量数据类型来实现acoi送代. 程序67分布式数组的定义.… .313 程序68子数组的定义 .314 七
XIII 程序 42 MPI_Scatterv应用示例.............................................................................................................132 程序 43 MPI_Allgather应用示例...........................................................................................................134 程序 44 MPI_Allgatherv应用示例.........................................................................................................135 程序 45 MPI_Alltoall使用示例..............................................................................................................137 程序 46 同步示例......................................................................................................................................139 程序 47 求p值............................................................................................................................................144 程序 48 错误的广播调用次序.................................................................................................................150 程序 49 错误的广播和点到点阻塞通信调用次序................................................................................150 程序 50 结果不确定的调用次序.............................................................................................................151 程序 51 归约操作MPI_MAXLOC示例....................................................................................................153 程序 52 用户自定义的归约操作...........................................................................................................155 程序 53 新数据类型的递交与释放.........................................................................................................165 程序 54 简单的MPI_ADDRESS调用示例 ..............................................................................................171 程序 55 包含多种不同类型的新MPI数据类型的定义.........................................................................172 程序 56 接收数据个数的获取.................................................................................................................174 程序 57 下三角矩阵数据类型的定义和使用........................................................................................176 程序 58 矩阵转置数据类型的定义.........................................................................................................177 程序 59 相同类型数据的打包和解包...................................................................................................179 程序 60 不同类型数据的打包与解包.....................................................................................................180 程序 61 一个完成的打包解包例子.......................................................................................................181 程序 62 创建进程组和通信域的简单示例............................................................................................190 程序 63 通信域的分裂与组间通信域的生成........................................................................................194 程序 64 属性的简单使用方法.................................................................................................................198 程序 65 在具有虚拟拓扑的进程组上进行数据传递............................................................................205 程序 66 用虚拟进程拓扑和向量数据类型来实现Jacobi迭代 ............................................................212 程序 67 分布式数组的定义.....................................................................................................................313 程序 68 子数组的定义..............................................................................................................................314
图列表 图1按指令(程序)数据的个数对并行计算机进行分类 3 图2按存储方式对并行计算机进行分类。 图3问题的并行求解时程 并行语言的实现方法 图5适合机群系统的SPMD并行算法的计算模式 图6计草与通信重叠的迩PD并行算法的计算模式 10 图7适合机带系统的PMD并行算法 图8第一个FORTRAN77+PI程序在1台机器上的执行结果 图9第 FORTRAN77+MPI程序在4台机器上的执行结果 、 图10第 个FORTRAN77+MPI程序的执行流程 图11第一个C+PI程序在1台机器上的执行结果 .19 图12第个C+MP1程序在4台机器上的执行结果 19 图3P1程序的框架结构 图14用的说明林式 33 图15MPI消息传递过 34 图I6 MPI SEND语句的消息信封和消总数热 图I7λMP1RECV语句的消息信封和消息数据 34 图18a在P消良发美和接收中的作用 34 图19数据在进程间的接力传送. 图20接力程序的输出结果 图21任意进程间相互问候 .4 图22接收任意源和任意标识的消忌 .46 图23总会死黄的酒信调用次序 47 图24不安全的通信调用次序 图25安全的通信调用次序 图26 Jacobi送代的数据划分及其与相应进程的对应 图27 Jacob送代的数据通信图示 .53 图28用PI SENDRECV实现/aCob送代示意图 57 图29矩阵向量乘 63 图30主讲程的按建与乱建打印 图3引按续与乱续打印的结果 68 图32标准通信模式 图33缓存通信模式 .71 图34同步通信模式. 75 图35黄绪酒信橙式 7 图36就绪发送例子各调用的时间关系图 图37 序的执行过程 82 图38配置文件的通用格式. .84 图39置文件示例 84 图40NT下启动PI程序的几种方式 XIV
XIV 图列表 图 1 按指令 程序 数据的个数对并行计算机进行分类 .....................................................................3 图 2 按存储方式对并行计算机进行分类..................................................................................................3 图 3 问题的并行求解过程...........................................................................................................................4 图 4 并行语言的实现方法...........................................................................................................................8 图 5 适合机群系统的SPMD并行算法的计算模式.................................................................................10 图 6 计算与通信重叠的SPMD并行算法的计算模式.............................................................................10 图 7 适合机群系统的MPMD并行算法..................................................................................................... 11 图 8 第一个FORTRAN77+MPI程序在1台机器上的执行结果..............................................................17 图 9 第一个FORTRAN77+MPI程序在4台机器上的执行结果..............................................................17 图 10 第一个FORTRAN77+MPI程序的执行流程...................................................................................18 图 11 第一个C+MPI程序在1台机器上的执行结果................................................................................19 图 12 第一个C+MPI程序在4台机器上的执行结果 ...............................................................................19 图 13 MPI程序的框架结构......................................................................................................................21 图 14 MPI调用的说明格式......................................................................................................................23 图 15 MPI消息传递过程..............................................................................................................................30 图 16 MPI_SEND 语句的消息信封和消息数据...................................................................................34 图 17 MPI_RECV语句的消息信封和消息数据.....................................................................................34 图 18 tag在MPI消息发送和接收中的作用............................................................................................34 图 19 数据在进程间的接力传送...............................................................................................................41 图 20 接力程序的输出结果.......................................................................................................................43 图 21 任意进程间相互问候.......................................................................................................................44 图 22 接收任意源和任意标识的消息.......................................................................................................46 图 23 总会死锁的通信调用次序...............................................................................................................47 图 24 不安全的通信调用次序...................................................................................................................48 图 25 安全的通信调用次序.......................................................................................................................49 图 26 Jacobi迭代的数据划分及其与相应进程的对应.........................................................................52 图 27 Jacobi迭代的数据通信图示..........................................................................................................53 图 28 用MPI_SENDRECV实现Jacobi迭代示意图..................................................................................57 图 29 矩阵向量乘........................................................................................................................................63 图 30 主进程的按续与乱续打印...............................................................................................................65 图 31 按续与乱续打印的结果...................................................................................................................68 图 32 标准通信模式....................................................................................................................................70 图 33 缓存通信模式....................................................................................................................................71 图 34 同步通信模式....................................................................................................................................75 图 35 就绪通信模式....................................................................................................................................77 图 36 就绪发送例子各调用的时间关系图..............................................................................................77 图 37 MPI程序的执行过程......................................................................................................................82 图 38 配置文件的通用格式.......................................................................................................................84 图 39 配置文件示例....................................................................................................................................84 图 40 NT下启动MPI程序的几种方式.....................................................................................................89
图41NT下运行P1程序配置文件的格式 图42NT上MPI配置文件示例(相同路径和名字) 图3NT上MPI配置文件示例2(不同路径和名字 9 图44NT上PI配置文件示例郎(一个机器上多个进程 .90 图45阻塞消息发送和接收 96 图46消息的接收次序 07 图47阻塞与非阻塞调用的对比 05 图50 对多通信 图51多对一桶信 123 图52多对多通信. 12 图3P同步用 12 图54 MP1组通信的计算功能 12 图55广播前后各进程缓区中数据的变化 120 图56数据收集 .128 图57数据散发」 130 图58组收集 133 图59MP ALLTOALL全互 139 图60MPI归约操作图方 图61求近似值方法的示意图 .142 图62求知值的近似人式 142 图63归约并散发操作 图64归约前后发送与接收缓冲区的对比 图65组归约操作前后发送与接收缓冲区的对 .1 图66归约并散发操作前后发送与接收发冲区的对比 .14 图67扫捕操作前后发送与接收缓冲风的比 149 图68类型图的图示 156 图69用PI TYPE CONTIGUOUS产生的新类型 15 图70用PT TOR产生的新数据类 图7I用MPLTYPE_INDEXED 生的新数据类型 16 图72用PI TYPE STRUCT生成的新类型 .163 图73卡氏诵信域的制分 203 图74简单的图拓扑 306 209 图76 各处理器上 明的包含通信边界 的局部数组 209 图77 二维网格上各处理器之间的通信关系 .210 图78组间通信域上的点到点通信 .260 图79组间通信域上的多对多组通信 261 图0组间酒信域上 过多或多过一通信 26 图81各进程创建的可供其它进程 的窗1 27 图82 PI PUT樂作图牙 27 图83 PI GET操作图示 273 图84对窗口数据的运算操作图示 273
XV 图 41 NT下运行MPI程序配置文件的格式...............................................................................................89 图 42 NT上MPI配置文件示例1 相同路径和名字 .............................................................................89 图 43 NT上MPI配置文件示例2 不同路径和名字 .............................................................................90 图 44 NT上MPI配置文件示例3 一个机器上多个进程 .................................................................90 图 45 阻塞消息发送和接收.......................................................................................................................96 图 46 消息的接收次序................................................................................................................................97 图 47 阻塞与非阻塞调用的对比...............................................................................................................98 图 48 不同类型的发送与接收的匹配.......................................................................................................99 图 49 标准非阻塞消息发送和接收.........................................................................................................100 图 50 一对多通信....................................................................................................................................123 图 51 多对一通信......................................................................................................................................123 图 52 多对多通信......................................................................................................................................124 图 53 MPI同步调用.................................................................................................................................124 图 54 MPI组通信的计算功能................................................................................................................125 图 55 广播前后各进程缓冲区中数据的变化........................................................................................126 图 56 数据收集........................................................................................................................................128 图 57 数据散发..........................................................................................................................................130 图 58 组收集..............................................................................................................................................133 图 59 MPI_ALLTOALL全互换 ...............................................................................................................136 图 60 MPI归约操作图示............................................................................................................................140 图 61 求p近似值方法的示意图...............................................................................................................142 图 62 求p值的近似公式...........................................................................................................................142 图 63 归约并散发操作..............................................................................................................................146 图 64 归约前后发送与接收缓冲区的对比............................................................................................147 图 65 组归约操作前后发送与接收缓冲区的对比................................................................................148 图 66 归约并散发操作前后发送与接收缓冲区的对比........................................................................148 图 67 扫描操作前后发送与接收缓冲区的对比....................................................................................149 图 68 类型图的图示..................................................................................................................................156 图 69 用MPI_TYPE_CONTIGUOUS产生的新类型..............................................................................158 图 70 用MPI_TYPE_VECTOR产生的新数据类型................................................................................159 图 71 用MPI_TYPE_INDEXED产生的新数据类型 ..............................................................................161 图 72 用MPI_TYPE_STRUCT生成的新类型.........................................................................................163 图 73 卡氏通信域的划分..........................................................................................................................203 图 74 简单的图拓扑..................................................................................................................................206 图 75 分块数组向虚拟处理器阵列的映射............................................................................................209 图 76 各处理器上声明的包含通信边界的局部数组............................................................................209 图 77 二维网格上各处理器之间的通信关系........................................................................................210 图 78 组间通信域上的点到点通信.........................................................................................................260 图 79 组间通信域上的多对多组通信.....................................................................................................261 图 80 组间通信域上一对多或多对一通信............................................................................................261 图 81 各进程创建的可供其它进程直接访问的窗口............................................................................271 图 82 MPI_PUT操作图示..........................................................................................................................272 图 83 MPI_GET操作图示.......................................................................................................................273 图 84 对窗口数据的运算操作图示.........................................................................................................273