
在上一版十分畅销的基础上,《大规模并行处理器编程实战(第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架构的编程特性。
编辑推荐
ACM SIGGRAPH计算机图形成就奖得主、美国国家工程院院士、NVIDIA院士、CUDA技术的创始人之一David B. Kirk最新作品,全面更新了并行编程方法和技术的内容,掌握并行计算思维和并行编程技巧,本书就“购”了 作者简介
David B. Kirk院士:美国国家工程院院士,NVIDIA院士、前首席科学家,也是CUDA技术的创始人之一,2002年曾荣获ACM SIGGRAPH计算机图形成就奖。他拥有麻省理工学院的机械工程学学士和硕士学位,加州理工学院的计算机科学博士学位。Kirk是50项与图形芯片设计相关的专利和专利申请的发明者,发表了50多篇关于图形处理技术的论文,是可视化计算技术方面的权威。
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.2GPGPU:一个中间步骤 27
2.3GPU计算 28
2.3.1可扩展的GPU 29
2.3.2发展近况 29
2.3.3未来发展趋势 30
参考文献与课外阅读 30
第3章CUDA简介 35
3.1数据并行性 36
3.2CUDA的程序结构 37
3.3向量加法kernel函数 39
3.4设备全局存储器与数据传输 41
3.5kernel函数与线程 46
3.6小结 50
3.6.1函数声明 50
3.6.2启动kernel函数 50
3.6.3预定义变量 51
3.6.4运行时API 51
3.7习题 51
参考文献 53
第4章数据并行执行模型 55
4.1CUDA的线程组织 56
4.2线程与多维数据的映射 59
4.3矩阵乘法——一个更加复杂的kernel函数 65
4.4线程同步和透明的可扩展性 70
4.5线程块的资源分配 73
4.6查询设备属性 74
4.7线程调度和容许时延 75
4.8小结 78
4.9习题 79
第5章CUDA存储器 81
5.1存储器访问效率的重要性 82
5.2CUDA设备存储器的类型 83
5.3减少全局存储器流量的一种策略 89
5.4分块矩阵乘法的kernel函数 93
5.5存储器——限制并行性的一个因素 98
5.6小结 100
5.7习题 101
第6章性能优化 103
6.1WARP和线程执行 104
6.2全局存储器的带宽 111
6.3执行资源的动态划分 118
6.4指令混合和线程粒度 120
6.5小结 121
6.6习题 121
参考文献 124
第7章浮点运算 127
7.1浮点格式 128
7.1.1M的规范化表示 128
7.1.2E的余码表示 129
7.2能表示的数 130
7.3特殊的位模式与IEEE格式中的精度 134
7.4算术运算的准确度和舍入 135
7.5算法的优化 136
7.6数值稳定性 137
7.7小结 141
7.8习题 141
参考文献 142
第8章并行模式:卷积 143
8.1背景 144
8.2一个基本算法:一维并行卷积 148
8.3常数存储器和高速缓存 149
8.4使用光环元素的分块一维卷积 153
8.5一个更简单的分块一维卷积——通用高速缓存 158
8.6小结 160
8.7习题 161
第9章并行模式:前缀和 163
9.1背景 164
9.2简单并行扫描 165
9.3考虑工作效率 169
9.4工作高效的并行扫描 170
9.5任意输入长度的并行扫描 174
9.6小结 177
9.7习题 177
参考文献 178
第10章并行模式:稀疏矩阵-向量乘法 179
10.1背景 180
10.2使用CSR格式的并行SpMV 183
10.3填充与转置 184
10.4用混合方法来控制填充 186
10.5通过排序和划分来规则化 189
10.6小结 191
10.7习题 191
参考文献 192
第11章应用案例研究:高级MRI重构 193
11.1应用背景 194
11.2迭代重构 197
11.3计算FHD 198
11.4最终评估 214
11.5习题 217
参考文献 218
第12章应用案例研究:分子可视化和分析 219
12.1应用背景 220
12.2kernel函数简单的实现方案 221
12.3线程粒度调节 225
12.4存储器合并 227
12.5小结 230
12.6习题 231
参考文献 232
第13章并行编程和计算思想 233
13.1并行计算的目标 234
13.2问题分解 235
13.3算法选择 238
13.4计算思想 243
13.5小结 244
13.6习题 244
参考文献 244
第14章OpenCL简介 245
14.1背景 246
14.2数据并行性模型 247
14.3设备的体系结构 249
14.4kernel函数 250
14.5设备管理和启动kernel 251
14.6OpenCL中的静电势图谱 254
14.7小结 258
14.8习题 258
参考文献 259
第15章OpenACC并行编程 261
15.1OpenACC与CUDA C的比较 261
15.2执行模型 263
15.3存储器模型 265
15.4基本的OpenACC程序 266
15.4.1并行构造 266
15.4.2循环构造 267
15.4.3kernels构造 272
15.4.4数据管理 275
15.4.5数据构造 276
15.4.6异步计算和数据传输 278
15.5OpenACC的发展方向 279
15.6习题 280
第16章Thrust:一个面向效率的CUDA编程库 281
16.1背景简介 282
16.2动机 284
16.3Thrust的基本特性 284
16.3.1迭代器和内存空间 286
16.3.2互操作性 286
16.4泛型编程 288
16.5抽象的益处 290
16.5.1编程效率 290
16.5.2鲁棒性 291
16.5.3真实性能 291
16.6最佳范例 293
16.6.1融合 293
16.6.2数组结构体 294
16.6.3隐式范围 296
16.7习题 297
参考文献 298
第17章CUDA FORTRAN 299
17.1CUDA FORTRAN和CUDA C的区别 300
17.2第一个CUDA FORTRAN程序 301
17.3CUDA FORTRAN中的多维数组 303
17.4用通用接口重载主机/设备端例程 304
17.5通过iso_c_binding调用CUDA C 307
17.6kernel循环指令和归约操作 309
17.7动态共享存储器 310
17.8异步数据传输 311
17.9编译和性能剖析 316
17.10在CUDA FORTRAN中调用Thrust 317
17.11习题 321
第18章C++ AMP简介 323
18.1C++ AMP核心特性 324
18.2C++ AMP执行模式详解 329
18.2.1显式和隐式的数据复制 330
18.2.2异步操作 331
18.2.3本节小结 333
18.3加速器管理 333
18.4分块执行 335
18.5C++ AMP图形特性 338
18.6小结 340
18.7习题 341
第19章异构集群编程 343
19.1背景简介 344
19.2运行示例 344
19.3MPI基础 346
19.4MPI点对点通信模型 348
19.5重叠计算和通信 355
19.6MPI集合通信模型 362
19.7小结 363
19.8习题 363
参考文献 364
第20章CUDA动态并行 365
20.1背景 366
20.2动态并行简介 367
20.3重要细节 368
20.3.1启动环境变量设置 369
20.3.2API错误和启动失败 369
20.3.3事件 369
20.3.4流 369
20.3.5同步范围 370
20.4内存可见性 371
20.4.1全局内存 371
20.4.2零拷贝内存 371
20.4.3常量内存 371
20.4.4局部内存 371
20.4.5共享内存 372
20.4.6纹理内存 372
20.5一个简单示例 373
20.6运行时限制 376
20.6.1内存占用 376
20.6.2嵌套深度 376
20.6.3内存分配和生存周期 376
20.6.4ECC错误 377
20.6.5流 377
20.6.6事件 377
20.6.7启动池 377
20.7一个更复杂的示例 378
20.7.1线性贝塞尔曲线 378
20.7.2二次贝塞尔曲线 378
20.7.3贝塞尔曲线计算(非动态并行版本) 378
20.7.4贝塞尔曲线计算(使用动态并行) 381
20.8小结 384
参考文献 384
第21章结论与展望 385
21.1重点回顾 385
21.2存储器模型的演变 386
21.2.1大型虚拟和物理地址空间 386
21.2.2统一的设备存储空间 388
21.2.3可配置的缓存和暂时存储器 388
21.2.4提高原子操作的速度 389
21.2.5提高全局内存的访问速度 389
21.3kernel函数执行控制过程的演变 389
21.3.1kernel函数内部的函数调用 389
21.3.2kernel函数中的异常处理 390
21.3.3多个kernel函数的同步执行 390
21.3.4可中断的kernel函数 391
21.4内核的性能 391
21.4.1双精度的速度 391
21.4.2更好的控制流效率 392
21.5编程环境 392
21.6美好前景 392
参考文献 393
附录A矩阵乘法主机版的源代码 395
附录BGPU的计算能力 407
序言
前言
我们很荣幸向大家介绍这本《大规模并行处理器编程实战(第2版)》。大众市场的计算系统,结合多核计算机处理单元(CPU)和多线程GPU计算,带来了万亿次计算能力的笔记本电脑和千万亿次的计算机集群。如此强大的计算能力,为我们在科研、工程、卫生和商业等领域使用计算机带来新的曙光。许多领域通过计算机系统将实验的规模、准确性、可控性和客观性等方面提升到前所未有的水平,将会在各自的领域实现突破。本书为实现这个愿景提供了一个关键因素:教授数以百万计的研究生和本科生学习并行编程,使他们拥有并行计算思维和并行编程技巧,从而应对无处不在的计算需求。
自从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课程的网站上可以下载几个这种示例)。
我们也鼓励读者在项目的选择过程中与导师不断交流。只要学生和导师都同意了某个项目,他们就会密切地联系、频繁地切磋并不断地报告项目的进展情况。我们试图为学生和导师之间的协作关系提供便利,不仅是为学生也是为导师增长宝贵的经验。
项目专题讨论
整个班级对彼此的最终项目的意见主要通过专题讨论进行交流。我们通常会安排6个报告厅来进行专题讨论。专题讨论是为学生设计的。例如,如果一个学生已经确定了项目,就可以把专题讨论作为一个提出初步想法、获取反馈意见和招募队友的场所。如果一个学生还没有确定自己的项目,他可以仅参加演讲和讨论并加入其中的一个项目组。在项目专题讨论期间,学生没有等级之分,这么做是为了营造一种和谐融洽的气氛,所以学生可以集中精力与导师、教学助理以及班上其他同学进行有意义的谈话。
有了专题讨论日程表后,导师和教学助理就可以花些时间给项目组提供反馈意见,以便学生可以提出问题。演讲的时间限制在10分钟内,因此在上课期间还有反馈和提问的时间。假设每次课90分钟,班级的大小最好限制在36人左右。为了严格控制时间并使反馈时间最大化,所有演示文稿预先加载到PC中。由于在专题讨论中并不是每个学生都会出席,因此每个班大概能容纳50个学生,可以根据需要提供额外的专题讨论时间。
导师和教学助理必须参加所有演讲,并给出有用的反馈意见。学生经常在下列问题上寻求帮助。第一,对于给定的时间,项目的规模是太大还是太小?第二,在这个领域中是否存在有利于这个项目的现有工作?第三,为并行执行而设立的目标计算是否适合CUDA编程模型?
设计文档
一旦学生决定选择某个项目并形成了团队后,我们就要求学生提交一个关于项目的设计文档。这有助于他们在正式进入项目前,思考整个项目的步骤。制定这种计划的能力对于他们将来事业的成功很重要。设计文档应该讨论项目的背景与目的,应用程序级目标和可能带来的影响,应用程序的主要特点,设计的概况,实现计划,它们的性能目标,经过论证的计划和可接受的测试,以及项目进度表。
在班级专题讨论会的前一周,教学助理对最终项目组进行一次项目检查。这个检查过程有助于确保学生没有偏离轨道,并且他们已经发现了设计过程早期存在的障碍。要求学生组带上他们最初的草案来检查,草案包括其应用程序的如下2个版本:(1)性能最优的CPU串行代码,采用SSE2和其他优化方案构建一系列健壮的基本代码,便于比较它们的速度;(2)性能最优的CUDA并行代码—— 这个版本是项目的主要成果。学生可以用这个版本认识到并行算法涉及额外的计算量时带来的系统开销。
学生组要准备好讨论每个版本代码的主要思想,任何浮点精度问题,任何针对应用程序之前结果的比较,以及显著地提高运行速度会对这个领域产生的影响。依我们的经验来看,在班级专题研讨会前一周进行检查,这是最佳的时间安排。如果时间太早,可能会把时间浪费在对不太成熟的项目和没有太大意义的会议上。如果时间太晚,学生就没有足够的时间根据反馈意见修订他们自己的项目。
项目报告
学生应该提交一份项目报告,这个报告讨论的是他们所在团队的主要发现。把6次课的时间放在一天,举行班级专题讨论会。在专题讨论会期间,学生所用的演讲时间正比于团队的规模。在演讲期间,学生要强调项目报告中做得最好的部分,这样也有益于整个班集体。演讲过程在学生的成绩中占的比例很高。每个学生必须单独回答一个直接向他提出的问题,因此同一个团队中每个学生的成绩也不相同。我们记录了之前的一些参与学习的情况,在ECE408网站上可以查看。专题研讨会为学生提供了制作简洁的演示文稿的大好机会,简洁的演示文稿能激发其他人阅读整篇文档。演讲结束后,学生要提交一份最终项目的完整报告。
在线补充
如果教师用本书作为课程的教材,就可以使用我们的实验安排、最终项目指南和示例项目说明。虽然本书提供了这些课程的知识性内容,但要想实现全部教学目标还应该查阅其他资料。我们也想邀请大家充分利用与本书相关的在线资料,这些资料可以在ELSEVIER出版社的网站上下载。
最后,我们鼓励读者提供反馈意见。如果读者有关于改进本书的任何想法或者对在线资料的补充,希望能反馈给我们。当然,我们也想知道读者喜欢本书的哪一方面。
ISBN | 9787302342724 |
---|---|
出版社 | 清华大学出版社 |
作者 | 柯克 (Kirk D.B. ) |
尺寸 | 16 |