本书内容简洁、直观、实用,强调计算思维能力和并行编程技巧。本书主要分为四个部分:第 一部分介绍异构并行计算编程的基础概念,包括数据并行化、GPU架构、CUDA编程及程序性能优化方法等内容;第二部分介绍并行模式,包括卷积、模板、并行直方图、归约、前缀和、归并等内容;第三部分介绍高级模式及应用,包括排序、稀疏矩阵计算、图遍历、深度学习、迭代式磁共振成像重建、静电势能图和计算思维等内容;第四部分介绍高级编程实践,包括异构计算集群编程、CUDA动态并行化等内容。本书不仅适合高等院校计算机相关专业的学生学习,也适合并行计算领域的技术人员参考。
第4版重要更新:·增加关于CUDA的新内容,包括较新的库,如CUDNN。·新增关于常用并行模式(模板、归约、排序)的章节,并对之前的章节(卷积、直方图、稀疏矩阵、图遍历、深度学习)进行了全面更新。·新增一章专门讨论GPU架构,包含Ampere等新的架构示例。·优化关于问题分解策略和性能方面的讨论,增加新的优化检查清单。
前 言
Programming Massively Parallel Processors: A Hands-on Approach, Fourth Edition
我们非常自豪地向你介绍本书。
融合多核CPU和多线程GPU的大众市场计算系统已经将万亿级别的计算能力引入笔记本电脑中,将亿亿级别的计算能力引入计算集群中。在如此强大的计算动能下,我们正处于科学、工程、医学以及商业领域广泛应用计算实验的黎明。我们也亲历了GPU计算在金融、电子商务、石油与天然气、制造等关键产业垂直市场的广泛渗透。通过具有前所未有的规模、精确度、安全性、可控性与可视性的计算实验,这些领域的突破将得以实现。本书为这一愿景提供了关键要素,即将并行编程教授给数百万研究生和本科生,使得计算思维和并行编程技能能够与微积分技能一样广泛普及。
本书的主要读者是所有需要通过计算思维和并行编程技能来取得科学与工程学科上的突破的研究生和本科生。此外,本书还被业内专业开发人员广泛使用,目标是在并行计算领域学习新的技能,与技术的飞速进步保持同步。这些专业开发人员涵盖机器学习、网络安全、自动驾驶、计算金融、数据分析、认知计算、机械工程、土木工程、电气工程、生物工程、物理学、化学、天文学以及地理学等领域,他们运用计算推动着各自领域前沿技术的发展。因此,这些开发人员既需要是领域专家,同时也必须是编程专家。本书通过逐步建立对技术的直观理解这一方式讲授并行编程。我们假设读者至少具备基本的C编程经验。我们选用了CUDA C这一并行编程环境,该环境需要NVIDIA GPU的支持。在大众消费者和专业人员手中已有超过10亿台这样的处理器,而超过40万名程序员在积极地运用CUDA进行开发。你在学习过程中开发出的应用程序,将有可能被非常庞大的用户社群所使用。
自2016年第3版上市以来,我们收到了许多来自读者和教师的宝贵意见。其中,很多人肯定了本书现有的非常重要的特点,其他人则提供了关于如何扩展本书内容以使其更具价值的建议。与此同时,自2016年以来,用于异构并行计算的硬件和软件技术已经取得了巨大的进步。在硬件领域,GPU计算架构已经推出了三代新版本,分别是Volta、Turing和Ampere。在软件领域,从CUDA 9到CUDA 11的发展使程序员得以访问新的硬件和系统功能。同时,新的算法也得到了开发。为适应这些变化,我们新增了四章,并对大部分现有章节进行了重写。
新增的四章包括一个基础性章节(第4章),以及三个关于并行模式和应用的章节(第8章、第10章和第13章)。我们增加这些章节的初衷如下:
第4章:在之前的版本中,关于架构和调度方面的讨论分布在多个章节中。在这一版中,我们将这些讨论集中在一起,以便感兴趣的读者学习。
第8章:在之前的版本中,模板模式在关于卷积的章节中略有提及,因为这两种模式有相似之处。在这一版中,第8章对模板模式进行了更为全面的介绍,强调其背后的数学原理,突出其与卷积不同的方面,从而为进一步的优化提供了可能。这一章还提供了处理三维网格和数据的示例。
第10章:在之前的版本中,归约模式在关于性能的章节中略有提及。在这一版中,第10章更为全面地呈现了归约模式,采用渐进的方式应用优化方法,并更深入地分析了相关的性能权衡。
第13章:在之前的版本中,归并排序在关于归并模式的章节中略有提及。在这一版中,第13章将基数排序作为一种极其适用于GPU并行化的非比较排序算法进行介绍。第13章采用渐进的方式进行优化,并分析了性能权衡。此外,这一章还对归并排序进行了探讨。
除了新增的章节外,所有章节都经过了修订,部分章节经过了大幅修改。这些章节包括:
第6章:之前在本章中的关于架构的内容已经移到第4章,归约示例部分则移至第10章。对于删改的部分,我们进行了重写以更全面地处理线程粒度问题,更为重要的是,提供一份常见的性能优化策略清单,并讨论了每种策略所解决的性能瓶颈。这份清单在本书的其余部分中被用来优化各种并行模式和应用程序的代码。我们的目标是强调一种用于优化并行程序性能的系统且渐进的方法。
第7章:在之前的版本中,关于卷积模式的章节以一维卷积作为示例,对二维卷积仅进行了简要处理。在这一版中,我们对本章进行了重写,从一开始就更加注重讨论二维卷积。这一变化使我们能够更全面地探讨更高维度平铺的复杂性和细节,并为读者学习卷积神经网络(第16章)提供更好的背景。
第9章:在之前的版本中,关于直方图模式的章节从一开始就应用了线程粗化优化,并将私有化优化与共享内存的使用相结合。在这一版中,我们对本章进行了重写,采用更渐进的方式进行性能优化。现在介绍的初始实现不再应用线程粗化,并将私有化和在私有bin中使用共享内存区分为两种独立的优化方式,前者旨在减少原子操作的争用,后者旨在减少访问延迟。线程粗化在私有化后应用,因为粗化的一个主要优点是减少提交到公共副本的私有副本数量。这种新的章节组织方式更加贴合本书始终遵循的系统化和渐进化的性能优化方法。此外,由于原子操作被用于多块归约和单次扫描核函数中,因此为了更早地引入原
胡文美(Wen-mei W. Hwu)
NVIDIA公司杰出研究科学家兼高级研究总监。伊利诺伊大学厄巴纳-香槟分校荣休教授,并行计算研究中心首席科学家。他在编译器设计、计算机体系结构、微体系结构和并行计算方面做出了卓越贡献,是IEEE Fellow、ACM Fellow,荣获了包括ACM-IEEE CS Eckert-Mauchly奖、ACM Grace Murray Hopper奖、ACM SIGARCH Maurice Wilkes奖在内的众多奖项。他拥有加州大学伯克利分校计算机科学博士学位。
大卫·B. 柯克(David B. Kirk)
美国国家工程院院士,NVIDIA Fellow,曾任NVIDIA公司首席科学家。2002年,他荣获ACM SIGGRAPH计算机图形学成就奖,以表彰其在把高性能计算机图形系统推向大众市场方面做出的杰出贡献。他拥有加州理工学院计算机科学博士学位。
伊扎特·埃尔·哈吉(Izzat El Hajj)
贝鲁特美国大学计算机科学系助理教授。他的研究方向是针对新兴并行处理器和内存技术的应用加速和编程支持,特别是GPU和存算一体。他拥有伊利诺伊大学厄巴纳-香槟分校电气与计算机工程博士学位。
目 录
Programming Massively Parallel Processors: A Hands-on Approach, Fourth Edition
译者序
推荐序
前言
致谢
第1章 引言 1
1.1 异构并行计算 2
1.2 为什么需要速度与并行性 5
1.3 加快实际应用的速度 6
1.4 并行编程中的挑战 7
1.5 相关的并行编程接口 8
1.6 本书的总体目标 9
1.7 本书的章节安排 10
参考文献 12
第一部分 基本概念
第2章 异构数据并行计算 14
2.1 数据并行性 14
2.2 CUDA C程序结构 16
2.3 向量加法核 17
2.4 设备全局存储和数据传输 19
2.5 核函数和线程 22
2.6 调用核函数 25
2.7 编译 27
2.8 总结 27
2.8.1 函数声明 27
2.8.2 内核调用和网格启动 27
2.8.3 内置(预定义)变量 28
2.8.4 运行时应用程序编程接口 28
练习 28
参考文献 30
第3章 多维网格和数据 31
3.1 多维网格组织 31
3.2 将线程映射到多维数据 33
3.3 图像模糊:更复杂的内核 38
3.4 矩阵乘法 41
3.5 总结 44
练习 44
第4章 计算架构和调度 46
4.1 现代GPU架构 46
4.2 块调度 47
4.3 同步和透明可扩展性 47
4.4 线程束和SIMD硬件 49
4.5 控制发散 53
4.6 线程束调度和延迟容忍 55
4.7 资源划分和占用率 56
4.8 查询设备属性 58
4.9 总结 60
练习 60
参考文献 61
第5章 内存架构和数据局部性 62
5.1 内存访问效率的重要性 62
5.2 CUDA内存类型 64
5.3 利用平铺减少内存流量 68
5.4 平铺的矩阵乘法内核 70
5.5 边界检查 74
5.6 内存使用对占用率的影响 76
5.7 总结 78
练习 78
第6章 性能方面的考虑 81
6.1 内存合并 81
6.2 隐藏内存延迟 87
6.3 线程粗化 91
6.4 优化清单 93
6.5 了解计算瓶颈 96
6.6 总结 96
练习 96
参考文献 97
第二部分 并行模式
第7章 卷积:常量内存和缓存 100
7.1 背景 100
7.2 并行卷积:一种基本算法 103
7.3 常量内存和缓存:概念与实例 105
7.4 边缘单元平铺卷积 108
7.5 使用边缘单元缓存的平铺卷积 111
7.6 总结 113
练习 113
第8章 模板 115
8.1 背景 115
8.2 并行模板:基本算法 118
8.3 用于模板扫描的共享内存平铺 119
8.4 线程粗化 121
8.5 寄存器平铺 123
8.6 总结 125
练习 125
第9章 并行直方图:原子操作和
私有化 126
9.1 背景 126
9.2 原子操作与基本直方图内核 128
9.3 原子操作的延迟和吞吐量 131
9.4 私有化 132
9.5 粗化 134
9.6 聚合 137
9.7 总结 138
练习 138
参考文献 139
第10章 归约和最小化发散 140
10.1 背景 140
10.2 归约树 141
10.3 一个简单的归约内核 143
10.4 最小化控制发散 145
10.5 最小化内存发散 148
10.6 最小化全局内存访问 149
10.7 对任意输入长度进行分层归约 150
10.8 利用线程粗化减少开销 152
10.9 总结 154
练习 154
第11章 前缀和(扫描):并行算法的工作效率 156
11.1 背景 156
11.2 基于Kogge-Stone算法的并行
扫描 158
11.3 关于速度与工作效率的考虑 162
11.4 基于Brent-Kung算法的并行
扫描 163
11.5 利用粗化提高工作效率 167
11.6 任意长度输入的分段并行扫描 168
11.7 利用单次扫描提高内存访问
效率 171
11.8 总结 172
练习 173
参考文献 173
第12章 归并:动态输入数据
识别 175
12.1 背景 175
12.2 串行归并算法 176
12.3 并行化方法 177
12.4 共秩函数的实现 178
12.5 基本并行归并内核 182
12.6 用于改进内存合并的平铺归并
内核 183
12.7 循环缓冲区归并内核 187
12.8 用于归并的线程粗化 192
12.9 总结 192
练习 193
参考文献 193
第三部分 高级模式及应用
第13章 排序 196
13.1 背景 196
13.2 基数排序 197
13.3 并行基数排序 198
13.4 内存合并优化 200
13.5 基值的选择 202
13.6 利用线程粗化改善合并 204
13.7 并行归并排序 205
13.8 其他并行排序方法 205
13.9 总结 206
练习 207
参考文献 207
第14章 稀疏矩阵计算 208
14.1 背景 208
14.2 具有COO格式的简单SpMV
内核 209
14.3 利用CSR格式分组非零行 211