大规模并行处理器编程实战(第2版)
基本信息
- 原书名:Programming Massively Parallel Processors: A Hands-on Approach, Second Edition
- 原出版社: Morgan Kaufmann
- 作者: David B. Kirk Wen-mei W. Hwu
- 译者: 赵开勇 汪朝辉 程亦超
- 出版社:清华大学出版社
- ISBN:9787302342724
- 上架时间:2013-12-3
- 出版日期:2013 年11月
- 开本:16开
- 页码:412
- 版次:1-1
- 所属分类:计算机 > 软件与程序设计 > 汇编语言/编译原理 > 综合
【插图】

内容简介
计算机书籍
在上一版十分畅销的基础上,《大规模并行处理器编程实战(第2版)》全面更新了并行编程方法和技术的内容。本书旨在综述并行编程,展示了专业人士和学生都可以使用的一种编程思维,以此来指导并行编程和优化应用程序,从而使性能得到显著提升。本书作者David B. Kirk和Wen-mei W. Hwu所采用的简洁、直观、实用的方法基于他们多年的并行计算课程实践。
第2版新增的内容
并行模式:包括多章并行模式内容,是并行编程应用中使用的很多并行算法的基础。
CUDA Fortran:新增的这一章介绍CUDA Fortran编程如何使用CUDA架构,其中讲解了几个CUDA Fortran编程的实用示例。
OpenACC:新增的这一章介绍一个开放的并行编程预编译指令,以实现并行编程简洁化的目的。
Thrust:Thrust库是CUDA C/C++的抽象层函数库。新增的这一章介绍了如何通过使用Thrust并行编程模板,对源程序只做简单的修改就可以使程序实现高性能。
C++ AMP:简单介绍了C++ AMP,它是由微软提出来的Windows环境下一套简化大规模并行处理器的编程接口。
NVIDIA的Kepler架构:探讨NVIDIA的高性能、低功耗的GPU架构的编程特性。
作译者
Wen-mei W. Hwu(胡文美)教授:拥有美国加州大学伯克利分校计算机科学博士学位,担任美国伊利诺伊大学厄巴纳-香槟分校(UIUC)协调科学实验室电气与计算机工程AMD创始人Jerry Sanders讲席教授(Walter J. SandersⅢAdvanced Micro Devices Endowed Chair)。胡文美教授还是IEEE(国际电气电子工程师学会)院士,ACM(美国计算机学会)院士。
目录
第1章 引言 1
1.1 异构并行计算 2
1.2 现代GPU的体系结构 6
1.3 为什么需要更高的速度和并行化 8
1.4 应用程序的加速 9
1.5 并行编程语言和模型 11
1.6 本书的总体目标 12
1.7 本书的组织结构 13
参考文献 16
第2章 GPU计算的发展历程 19
2.1 图形流水线的发展 19
2.1.1 固定功能的图形流水线时代 20
2.1.2 可编程实时图形流水线的发展 23
2.1.3 图形与计算结合的处理器 25
2.2 GPGPU:一个中间步骤 27
2.3 GPU计算 28
2.3.1 可扩展的GPU 29
2.3.2 发展近况 29
2.3.3 未来发展趋势 30
译者序
2007年,NVIDIA公司推出了CUDA(Compute Unified Device Architecture,统一计算设备架构)这一编程模型的1.0版本。作为译者,我有幸于2007年底就开始接触CUDA。这几年间,异构高性能计算不断发展,支持异构计算的架构不断更新和涌现,越来越多的人开始关注异构高性能计算。在大数据时代,异构高性能计算是处理大数据的一把利器。传统并行计算算法的研究在20世纪60年代和70年代非常活跃,现在的很多并行算法实际上在那个时代都已出现。技术的不断发展,芯片的高度集成,使得以前需要用大规模计算集群完成的工作,现在可在一个小芯片上完成,从而使高性能并行计算得以普及。高性能计算小芯片(包括多核心CPU、GPU、众核核心协处理器等)使万亿次计算走向了单个节点。除了高性能计算集群外,个人高性能计算机和移动平台都会用到高性能编程技术。高性能编程技术在个人计算机和移动平台将成为未来的一个发展方向。针对移动平台的高性能计算,将来也会是一个重要领域。且计算和传输本就是一体的,为在降低传输带宽的同时达到高质量的传输,越来越多的新协议需要大量的计算。单节点的高性能计算能力,可以很好地解决计算部分的问题。
硬件的变革要求我们紧跟国际步伐,在这几年的TOP 500排名中,中国多次排名前列。但是,对于高性能计算而言,光有硬件架构往往是不够的。近几年硬件的变化基本是18个月左右革新一次。如果没有优秀软件的支持,再好的硬件也很快就会过时,投入的大量人力物力就会在几年之内迅速贬值。对于新的硬件架构必须开发新的软件,全世界基本是在同一条起跑线上。我们希望更多的开发者加入到异构高性能开发中来。高性能异构计算也是解决大数据的一个强有力手段。
本书首先讲述硬件的体系结构,以GPU为例讲解异构计算芯片的架构,然后结合实际开发示例,讲解软件系统结构,以及异构高性能计算软件开发的思想和实践。异构高性能计算芯片的发展近几年非常活跃,作为译者,我们希望,通过翻译本书,能架起知识传播的桥梁,将国外的最新技术传播给国内的读者。
感谢清华大学出版社对我们的信任,把这本重要的书交给我们翻译。感谢参与校对和审稿的同仁们:武汉某研究所的周学谦,香港中文大学的王若薇,武汉大学的方留杨,香港科技大学的李佳俐,北京师范大学的赵国兴,中国科技大学近代力学系的冉伟,香港浸会大学异构计算实验室的梅辛欣,中科院超算中心的黄潘育,华大基因的张帆。没有你们的支持与帮助,本书将无法顺利付梓。在此,还要由衷地感谢我的导师褚晓文老师,感谢您对我的支持与鼓励。
异构高性能计算不断发展,翻译本书旨在为传播知识做一点绵薄之力。书中所涉及的领域比较广泛,翻译中如有不当之处,敬请广大读者批评指正。
再次向参与、支持和关切本书出版的同仁表示诚挚的谢意!
赵开勇
2013年7月4日
于香港浸会大学计算机系异构计算实验室
致 谢
有很多人为我们出版第2版提供了帮助。首先需要感谢本书新章节的作者。Yuan Lin和Vinod Grover撰写了OpenACC这一章的初稿。Nathan Bell和Jared Hoberock在Chris Rodrigues的基础上撰写了Thrust这章的初稿。Greg Ruetsch和Massimiliano Fatica撰写了CUDA FORTRAN这章的初稿。David Callahan撰写了C++ AMP这一章。Isaac Gelado撰写了MPI-CUDA这章的初稿。Brent Oster为Kepler章节提供了原始资料和代码实例。如果没有这些人的帮助,我们就不能深入地将这些内容提供给读者。
非常感谢Izzat E1 Hajj,他不厌其烦地帮我们验证代码示例并改善插图和练习题的质量。
也要特别感谢CUDA之父Ian Buck和Tesla GPU 计算架构的首席架构师John Nickolls。他们的团队为这个课程提供了优秀的基础设施。在我们撰写第2版本的时候,John与世长辞。我们非常怀念他。Nadeem Mohammad组织NVIDIA修订和提供了附录B。Bill Bean、Simon Green、Mark Harris、Nadeem Mohammad、Brent Oster、Peter Shirley、Eric Young和Cyril Zeller对手稿进行了修订和校对。Calisa Cole帮助设计了封面。Nadeem的无私分享为这本书的完成起到了关键性的作用。
尤其要感谢Jensen Huang提供大量人力物力开设这门课程,为本书的出版奠定了基础。Tony Tamasi的团队为本书提供了大量的评论和修订建议。Jensen还花费了大量时间阅读早期的草稿,为我们提供了很有价值的反馈。David Luebke为这个课程提供了GPU计算资源。Jonah Alben提供了颇有价值的见解。Michael Shebanow和Michael Garland给予了友情讲座和教学材料。
伊利诺伊的John Stone和Sam Stone为案例研究和OpenCL章节提供了大量的基础材料。John Stratton和Chris Rodrigues为编程思维这一章提供了素材。I-Jui“Ray”Sung、John Stratton、Xiao-Long Wu和Nady Obeid在他们的研究之外自愿担当助教,提供了实验素材并帮助改进课程材料。Jeremy Enos孜孜不倦地工作,使学生有一个稳定的、用户友好的GPU计算集群用于实验和项目研究。
感谢Dick Blahut让我们在伊利诺伊大学有挑战性地开展了这个课程。他不断提醒我们需要写这一本书来帮助我们不断前行。Beth Katsinas安排了一次与Dick Blahut和NVIDIA的副总Dan Vivoli的会议。通过这次会议,向David介绍了Blahut,也促使David和Wen-mei在伊利诺伊大学开设这门课程。
也要感谢伊利诺伊大学的Thom Dunning和密歇根大学的Sharon Glotzer,作为计算机科学和工程虚拟大学的副执行长,他们盛情举办了暑期课程。Trish Barker、Scott Lathrop、Umesh Thakkar、Tom Scavo、Andrew Schuh和Beth McKown都参与组织了暑期课程。Robert Brunner、Klaus Schulten、Pratap Vanka、Brad Sutton、John Stone、Keith Thulborn、Michael Garland、Vlad Kindratenko、Naga Govindaraju、Yan Xu、Arron Shinn和Justin Haldar为暑期课程提供了教材和课程计划。
Nicolas Pinto在MIT的课程中测试了早期版本的前几章,然后提供了非常有价值的反馈和修改建议。Steve Lumetta和Sanjay Patel讲授了不同版本的课程,为我们提供了有价值的建议。John Owens非常友善地为我们提供了他的幻灯片。Tor Aamodt、Dan Connors、Tom Conte、Michael Giles、Nacho Navarro和全世界许许多多的教员以及他们的学生为我们提供了非常有价值的反馈信息。
尤其要感谢我们的同事 Kurt Akeley、Al Aho、Arvind、Dick Blahut、Randy Bryant、Bob Colwell、Ed Davidson、Mike Flynn、John Hennessy、Pat Hanrahan、Nick Holonyak、Dick Karp、Kurt Keutzer、Dave Liu、Dave Kuck、Yale Patt、David Patterson、Bob Rao、Burton Smith、Jim Smith和Mateo Valero。他们抽出时间来与我们一起分享积累多年的知识。
前言
自从2010年第1版出版以来,我们收到了读者和老师的很多建议。许多人提出他们重视的一些现有功能。另一些人给我们提出了如何丰富内容的建议,从而使本书更有价值。此外,异构并行计算的硬件和软件已经越来越先进。在硬件领域,自从此书第1版出版以后,至少两款通用图像显示卡(GPU)计算架构—— Fermi和Kepler已发布。在软件领域,CUDA 4.0和CUDA 5.0也可以让程序员使用Fermi和Kepler的新特性。因此,我们增加了8章新的内容并几乎重写了5章已有的内容。
总的来说,我们在保留第1版很多有用内容的基础上,增加了3部分主要的内容。第1个增加的部分是更系统地讲解了并行编程。具体内容包括:(1)新增了第8、9和10章来介绍常用的基本并行算法模式;(2)在第3、4、5和6章中增加了更多的背景材料;(3)在第7章中增加了数值稳定性的处理。这些增加的内容皆在消除“学生已经熟悉基本并行编程概念”的假设。我们还通过更多的例子来帮助读者理解。
第2个增加的部分是在异构并行计算系统中采用MPI-CUDA模型的并行编程实践。这一部分内容是大量读者希望增加的部分。鉴于GPU的成本效益明显以及单位瓦特的高吞吐量,现在许多高性能计算系统在每个节点中都使用了GPU。新增加的第19章在概念上解释了这些系统编程接口背后的框架。
第3个增加的部分是介绍了新的并行编程接口和工具,这些都可以用来加快数据并行编程。新增加的第15、16、17和18章介绍了OpenACC、Thrust、CUDA FORTRAN和C++ AMP。与介绍这些工具的用户使用手册不同,我们更注重于从概念上理解使用上面这些工具解决的编程问题。
虽然我们做了这些改进,但也保留了第1版的特性,这似乎有助于它的受欢迎程度。首先,我们尽可能保证本书简洁。虽然我们非常想增加更多有用的材料,但还是希望尽量减少页数。第二,我们尽量直观地解释问题。虽然一些概念是非常形式化的,特别是介绍基本并行算法时,但我们尽量使讲解直观而实用。
读者对象
本书的读者对象是研究生和本科生,他们来自各种科学学科和工程学科,他们的学科中需要用到计算思维能力和并行编程技巧,通过用已经普及的万亿次运算硬件能使他们在自己的领域中有所突破。我们假设读者至少已经具备了基本的C语言编程经验,因此不管是在计算机科学领域内还是领域外,他们都是比较高级的程序员。我们专门面向计算领域内的科学家,如机械工程、土木工程、电气工程、生物工程、物理、化学、天文学和地理学,这些科学家将通过计算在他们各自的领域中做进一步的研究。正因为这样,这些科学家既是他们领域内的专家,也是高级程序员。本书采用基本的C语言编程技巧,教大家用C语言进行并行编程。我们使用CUDA C并行编程环境(NVIDIA公司开发的GPU上支持它,并可以在CPU上进行模拟)。大约有3.75亿左右的处理器被用户和专业人士在使用,其中超过120 000的程序员在积极地使用CUDA。读者作为学习经验的一部分而开发的应用程序将会被一个庞大的用户社区使用。
如何使用本书
我们愿意提供在本书教学过程中的一些经验。从2006年开始,我们讲了多个类型的课程:采用为期一学期的模式和为期一周的密集模式。原来的ECE498AL课程在伊利诺伊大学香槟分校已成为一个永久的课程,称为ECE408或CS483。当我们开设ECE498AL这门课的时候,开始了一些早期章节的撰写。前面4章在2009年的春天由Nicolas Pinto在MIT课程中进行了测试。从那时起,我们已经在众多的学校(包括VSCSE和PUMPS暑期学校)使用这本书。
分3个阶段的学习方法
为了能同时兼顾ECE498AL的课程和编程作业,我们把学习过程分成3个阶段:
第1个阶段——基于第3章的一次课致力于教会学生CUDA基本的存储器和线程模型、CUDA对C语言的扩展和基本的编程与调试工具。在这次课后,学生要能在几个小时内编出简单矢量相加的代码。随后的4个课时,让学生从概念上理解CUDA的内存模型、CUDA线程执行模型、GPU硬件特性和现代计算机体系架构。这些课时基于第4、5和6章的内容。
第2个阶段—— 一系列的课时涵盖并行计算中的浮点数问题和在高性能并行应用中需要的数据并行编程模式。这些课时基于第7~第10章。经过这个阶段的学习,矩阵乘法的代码性能提高了近10倍。在这一阶段,学生还应该完成关于卷积、向量归约和前缀扫描的学习。
第3个阶段—— 一旦学生掌握了CUDA基本的编程技巧,剩下的课程内容涵盖计算思想、各种并行执行模型和并行编程规则。这些课的内容对应于第11~第20章(这些课程的录音和视频可以从网上下载(http://courses.engr.illinois.edu/ece408/))。
把所有内容连贯起来:最终项目
当读者通过这门课、实验和本书的章节掌握了基础知识后,最终项目把所学到的经验联系起来。最终项目对这门课十分重要,它在这门课中的地位很显眼,大概需要花费两个月的时间。它采用了5个创新点:指导、专题讨论、检查、最终的报告和专题讨论会(在ECE408的网站上可以下载最终项目的更多信息,我们想提供对这些设计因素的深入思考)。
我们鼓励学生选取目前研究领域中一些具有挑战性的问题作为他们的最终项目。在这个过程中,指导老师会成立计算科学研究小组来提出问题,这些研究小组担当导师的角色。我们要求导师提供一两页的项目规格说明表,简单地描述应用程序的重要性,导师想要学生组在应用程序中完成的工作,了解与开发应用程序所需要具有的技术和技能(特定类型的数学、物理或化学课程),以及一个网站和传统资源列表。学生可以利用这些表中对应的内容了解技术背景、总体信息构建模块,以及特定的实现方式和代码示例对应的具体的URL或FTP路径。这些项目说明表也应该为学生提供学习经验,在以后的工作当中可以定义他们自己的研究项目(在ECE408课程的网站上可以下载几个这种示例)。
我们也鼓励读者在项目的选择过程中与导师不断交流。只要学生和导师都同意了某个项目,他们就会密切地联系、频繁地切磋并不断地报告项目的进展情况。我们试图为学生和导师之间的协作关系提供便利,不仅是为学生也是为导师增长宝贵的经验。
项目专题讨论
书摘
本章内容:
异构并行计算
现代GPU的体系结构
为什么需要更高的速度和并行化
应用程序的加速
并行编程语言和模型
本书的总体目标
本书的组织结构
参考文献
近20年来,基于单个中央处理单元(Central Processing Unit,CPU)的微处理器,如Intel的奔腾(Pentium)系列和AMD的皓龙(Opteron)系列,很好地推动了计算机应用程序的性能提升和成本降低。正是这些微处理器,使得桌面计算机的浮点运算可以达到每秒十亿次(Giga FLoating-point OPerations per Second,GFLOPS),而集群服务器甚至可以达到每秒万亿次(Tera FLoating-point OPerations per Second,TFLOPS)。一方面,性能的飞速提升使应用软件行业提供更多功能强大的、用户界面友好的、可用性更高的软件成为可能。另一方面,用户一旦适应了这些改进,对性能的需求也会不断地提升。这在计算机行业形成了一个很好的良性循环。
然而,自2003年以来,由于能耗和散热问题限制了时钟频率的提高和单CPU在每个时钟周期中的执行能力,因此仅凭硬件性能的提升来提高应用程序的运行速度已经远远不够了。实际上,所有微处理器供应商已经转变了处理器的处理模型,即在每个芯片中采用多个处理单元(称为处理器内核,Processor Core)提升处理能力,这种转变在软件开发人员社区中产生了巨大的影响[Sutter2005]。
传统的绝大部分软件应用程序都是用串行方式编写的,冯·诺依曼早在1945年的开创性报告中就提出了这一方式[vonNeumann1945]。这些串行程序的顺序执行过程符合人们的顺序思维习惯,容易被人们理解。从计算机发展史上看,大部分软件开发人员都依赖于硬件的发展从底层上加速串行应用程序。每产生一代新的微处理器,计算机用户就习惯性地期待程序的运行变得更快,但用户的这种期待从现在起变得很难实现。一个串行程序只能在一个微处理器内核中运行,目前单个微处理器的运行速度已经到达一个瓶颈阶段,很难再有所突破。运行速度的限制使得应用程序开发人员很难随着新一代微处理器的引入而在其软件中引进新的特性与功能,从而阻碍了整个计算机行业的发展进程。
而每一代微处理器产生的同时也会对应用软件的性能提出更高的要求,于是并行程序应运而生,它采用多线程协作的执行方式使程序运行得更加快速。这种新的设计方式(并行程序设计)的发展极大地推动了产业的进步,甚至称为“并行革命(concurrency revolution)”[Sutter2005]。现在运用并行程序设计已经不足为奇,并行程序在高性能计算领域已经发展了几十年。但这些并行程序只能在昂贵的大型计算机上运行,而只有少数高端的应用程序值得用这么昂贵的计算机,因此也只有少数开发人员能运用并行程序设计。既然新的微处理器都是并行计算机,并行程序就应该随之得到广泛应用,从而开发出更多的并行应用程序。这需要大量的软件开发人员掌握并行程序设计,而这也正是本书的出发点。
1.1 异构并行计算
自2003年以来,半导体行业在设计微处理器时形成了两个主要方向[Hwu2008]。多核(multicore)方向试图把串行程序移植在多核上,运行时仍然能保持串行程序的执行速度。多核时代从双核处理器开始,内核的数量大致随半导体生产工艺的改进而翻倍。目前多核处理器最好的例子就是Intel公司生产的酷睿i7系列微处理器,它的处理器有4个内核,每个内核都是乱序执行、多指令流出的微处理器,每个内核能执行X86指令集中的所有指令;每个处理器由两个硬件线程来支持超线程,这种设计使得串行程序的执行速度得以最大化。相比之下,多线程(many-thread)方向则更侧重于执行并行应用程序时的吞吐量。多线程处理器支持的线程数量也随着计算机的更新换代不断翻番。目前最典型的例子是NVIDIA公司生产的GTX680系列图形处理单元(Graphics Processing Unit,GPU),它支持16 384个线程以简单而有序的流水线方式执行。
从2003年开始,多线程处理器(尤其是GPU)已经成为提升浮点运算性能的引领者。截至2012年,多线程GPU与多核CPU在峰值浮点运算的吞吐量方面的比率已经高达10:1。这仅仅是芯片中的执行资源可以支持的原始速度,而不一定是应用程序在运行时可以达到的速度。在2012年,GPU双精度浮点运算的执行速度可以达到每秒1.5万亿次(1.5 teraflops,1500 gigaflops),而多核CPU的执行速度只能达到每秒1500亿次(150 gigaflops)。
这种并行方式与传统的串行方式相比,其执行能力之间的差距相当大,目前GPU的执行能力已经达到了一定的水准,这种水准可以由一个称之为“电位(electrical potential)”的临界状态来衡量。迄今为止,正是并行程序与串行程序之间的巨大性能差距,使得很多应用程序开发人员将其软件中的密集计算部分转移到GPU中执行。毫无疑问,这些密集计算部分也是早期并行程序设计的重点之一。当工作量增大时,研究人员把工作细分给每个合作者。
有人可能会问,为什么多线程GPU和通用多核CPU之间的性能差距这么大。答案在于这两种处理器采用了完全不同的设计理念,如图1-1所示。优化CPU设计的目的主要是为了提高串行代码的性能,它采用复杂的控制逻辑,用指令来控制单线程可执行程序的并行执行,即便这些程序不按顺序执行,至少也是可串行执行的。更重要的是,CPU使用了大量缓存,一方面可以减少访问复杂应用程序的指令和数据时产生的延时,另一方面还能够节约带宽。无论是缓存还是控制逻辑,都不利于提升峰值计算速度。到了2012年,高端通用多核微处理器通常采用6~8个处理器内核和多兆字节的片上高速缓存,旨在大幅提升串行代码的性能。
图1-1 CPU和GPU不同的设计理念