并行计算与高性能计算

目 录内容简介
第Ⅰ部分 并行计算介绍
第1 章 为什么使用并行计算 3
1.1 为什么要学习并行计算 5
1.1.1 并行计算的潜在优势是什么 7
1.1.2 并行计算的注意事项 9
1.2 并行计算的基本定律 9
1.2.1 并行计算的极限:Amdahl 定律 9
1.2.2 突破并行极限:Gustafson-Barsis定律 10
1.3 并行计算如何工作 12
1.3.1 应用程序示例 13
1.3.2 当今异构并行系统的硬件模型 18
1.3.3 当今异构并行系统的应用程序模型及软件模型 21
1.4 对并行方法进行分类 24
1.5 并行策略 25
1.6 并行加速与比较加速:两种不同的衡量标准 26
1.7 你将在本书中学到哪些内容 27
1.7.1 扩展阅读 27
1.7.2 练习 28
1.8 本章小结 28
第2 章 规划并行化 29
2.1 处理新项目:准备工作 30
2.1.1 版本控制:为并行代码创建一个安全的存储库 31
2.1.2 测试套件:创建健壮、可靠的应用程序的优质步 32
2.1.3 查找和修复内存问题 40
2.1.4 提高代码的可移植性 41
2.2 概要分析:探测系统功能和应用程序性能之间的差距 42
2.3 计划:成功的基础 42
2.3.1 探索benchmark 和mini-apps 43
2.3.2 核心数据结构和代码模块化设计 43
2.3.3 算法:重新设计并行 44
2.4 实施 44
2.5 提交:高质量的打包过程 45
2.6 进一步探索 46
2.6.1 扩展阅读 46
2.6.2 练习 46
2.7 本章小结 46
第3 章 性能极限与分析 49
3.1 了解应用程序的潜在性能限制 49
3.2 了解硬件性能:基准测试 52
3.2.1 用于收集系统特征的工具 52
3.2.2 计算浮点运算的最大理论值 55
3.2.3 内存层级和理论内存带宽 55
3.2.4 带宽和浮点运算的实证测量 56
3.2.5 计算flop 和带宽之间的机器平衡 59
3.3 描述你的应用程序:分析 59
3.3.1 分析工具 60
3.3.2 处理器时钟频率和能耗的实证测量 69
3.3.3 在运行时跟踪内存 70
3.4 进一步探索 71
3.4.1 扩展阅读 71
3.4.2 练习 71
3.5 本章小结 71
第4 章 数据设计和性能模型 73
4.1 数据结构与性能:面向数据的设计 74
4.1.1 多维数组 76
4.1.2 结构数组(AoS)与数组结构(SoA) 80
4.1.3 数组结构的数组(AoSoA) 85
4.2 缓存未命中的3C:强制、容量与冲突 86
4.3 简单性能模型:案例研究 90
4.3.1 全矩阵数据表示 92
4.3.2 压缩稀疏存储表示 95
4.4 高级性能模型 98
4.5 网络消息 101
4.6 进一步探索 103
4.6.1 扩展阅读 104
4.6.2 练习 104
4.7 本章小结 104
第5 章 并行算法与模式 105
5.1 并行计算应用的算法分析 105
5.2 性能模型与算法复杂性 106
5.3 什么是并行算法 109
5.4 什么是哈希函数 110
5.5 空间哈希:一种高并行度算法 111
5.5.1 使用优质哈希进行空间网格操作 113
5.5.2 使用紧凑哈希进行空间网格操作 126
5.6 prefix sum(扫描)模式及其在并行计算中的重要性 132
5.6.1 Step-efficient 并行扫描操作 133
5.6.2 Work-efficient 并行扫描操作 134
5.6.3 用于大型数组的并行扫描操作 135
5.7 并行全局和:解决关联性问题 135
5.8 并行算法研究的未来 141
5.9 进一步探索 141
5.9.1 扩展阅读 141
5.9.2 练习 142
5.10 本章小结 142
第II 部分 CPU:并行的主力第6 章 向量化:免费的flop 145
6.1 向量及单指令多数据流(SIMD)概要 145
6.2 向量化的硬件趋势 146
6.3 向量化方法 147
6.3.1 使用优化软件库可以轻松提高性能 148
6.3.2 自动向量化:向量化加速的简单方法(大多数情况下) 148
6.3.3 通过提示来指导编译器:pragma和指令 152
6.3.4 使用向量本征库处理无法向量化的循环 157
6.3.5 大胆尝试:使用汇编代码进行向量化 162
6.4 实现更好向量化的编程风格 163
6.5 与编译器向量化相关的编译器标志 164
6.6 使用OpenMP SIMD 指令实现更好的移植性 170
6.7 进一步探索 172
6.7.1 扩展阅读 172
6.7.2 练习 172
6.8 本章小结 173
第7 章 使用OpenMP 实现并行计算 175
7.1 OpenMP 介绍 175
7.1.1 OpenMP 概念 176
7.1.2 OpenMP 简单程序示例 179
7.2 典型的OpenMP 用例:循环级OpenMP、高级OpenMP 和MPI +OpenMP 183
7.2.1 使用循环级OpenMP 进行快速并行化 184
7.2.2 使用高级OpenMP 获得更好的并行度 184
7.2.3 使用MPI + OpenMP 获得极限可扩展性 185
7.3 标准循环级OpenMP 示例 185
7.3.1 循环级OpenMP:向量加法示例 186
7.3.2 stream triad 示例 189
7.3.3 循环级OpenMP:stencil 示例 190
7.3.4 循环级示例的性能 191
7.3.5 使用OpenMP 线程的global sum的约减示例 192
7.3.6 循环级OpenMP 的潜在问题 193
7.4 OpenMP 中变量范围对结果准确性的重要性 193
7.5 函数级OpenMP:使整个函数实现线程并行 194
7.6 使用高级OpenMP 改进并行可伸缩性 196
7.6.1 如何实现高级OpenMP 197
7.6.2 实现高级OpenMP 的示例 199
7.7 使用OpenMP 混合线程及向量化 201
7.8 使用OpenMP 的高级示例 204
7.8.1 在x 和y 方向单独传递的stencil示例 204
7.8.2 使用OpenMP 线程实现kahan求和 208
7.8.3 通过线程实现的prefix scan算法 209
7.9 线程工具对健壮程序的重要性 210
7.9.1 使用Allinea/ARM MAP快速获得应用程序的高层概要文件 211
7.9.2 使用Intel Inspector 查找线程竞态条件 212
7.10 基于任务的支持算法示例 213
7.11 进一步探索 214
7.11.1 扩展阅读 214
7.11.2 练习 215
7.12 本章小结 215
第8 章 MPI:并行骨干 217
8.1 MPI 程序基础 217
8.1.1 为每个MPI 程序进行基本MPI函数调用 218
8.1.2 简单MPI 程序的编译器包装器 219
8.1.3 使用并行启动命令 219
8.1.4 MPI 程序的最小工作示例 219
8.2 用于进程间通信的发送和接收命令 221
8.3 聚合通信:MPI 的强大组件 227
8.3.1 使用barrier 来同步计时器 228
8.3.2 使用广播处理小文件输入 228
8.3.3 使用约减从所有进程中获取单个值 230
8.3.4 使用gather 在调试打印输出中排序 233
8.3.5 使用scatter 和gather 将数据发送到工作进程 234
8.4 数据并行示例 236
8.4.1 使用stream triad 来测量节点上的带宽 236
8.4.2 二维网格中的ghost cell 交换 238
8.4.3 三维stencil 计算中的ghost cell交换 244
8.5 使用高级MPI 功能来简化代码和启用优化 245
8.5.1 使用自定义MPI 数据类型来简化代码并提升性能 245
8.5.2 MPI 中的笛卡儿拓扑 250
8.5.3 ghost cell 交换变体的性能测试 255
8.6 通过联合使用MPI 和OpenMP实现极高的可扩展性 257
8.6.1 混合MPI 和OpenMP 的优势 257
8.6.2 MPI 与OpenMP 混合示例 258
8.7 进一步探索 259
8.7.1 扩展阅读 260
8.7.2 练习 260
8.8 本章小结 261
第III 部分 GPU:加速应用程序运行
第9 章 GPU 架构及概念 265
9.1 作为加速计算平台的CPU-GPU
系统 266
9.1.1 集成GPU:商业化系统中没有被充分使用的资源 267
9.1.2 独立GPU:高性能计算的主力 267
9.2 GPU 和线程引擎 268
9.2.1 使用流多处理器(或子片)作为计算单元 270
9.2.2 作为独立处理器的处理单元 270
9.2.3 每个处理单元进行多个数据操作 270
9.2.4 计算GPU flop 的理论峰值 270
9.3 GPU 内存空间的特点 272
9.3.1 计算内存带宽的理论峰值 273
9.3.2 测量GPU stream benchmark 274
9.3.3 GPU 的Roofline 性能模型 275
9.3.4 使用mixbench 性能工具为工作负载选择GPU 276
9.4 PCI 总线:CPU 与GPU 之间的数据传输桥梁 278
9.4.1 PCI 总线的理论带宽 279
9.4.2 PCI 带宽benchmark 应用程序 281
9.5 多GPU 平台和MPI 284
9.5.1 优化网络中GPU 之间的数据移动 284
9.5.2 一种比PCI 总线性能更高的替代方案 285
9.6 GPU 加速平台的潜在收益 286
9.6.1 缩短解决问题的时间 286
9.6.2 使用GPU 降低能耗 287
9.6.3 使用GPU 降低云计算成本 292
9.7 何时使用GPU 292
9.8 进一步探索 292
9.8.1 扩展阅读 293
9.8.2 练习 293
9.9 本章小结 293
第10 章 GPU 编程模型 295
10.1 GPU 编程抽象:通用框架 296
10.1.1 大规模并行处理 296
10.1.2 无法在任务之间进行协调 297
10.1.3 GPU 并行性的术语 297
10.1.4 将数据分解成独立的工作单元:NDRange 或网格 297
10.1.5 为工作组提供大小合适的工作块 300
10.1.6 通过lockstep 执行子工作组、warp 与wavefront 300
10.1.7 工作项:操作的基本单元 301
10.1.8 SIMD 或向量硬件 301
10.2 GPU 编程模型的代码结构 302
10.2.1 “Me”编程:并行kernel的概念 302
10.2.2 线程索引:将本地tile 映射到全局中 303
10.2.3 索引集 304
10.2.4 如何在GPU 编程模型中对内存资源进行寻址 305
10.3 优化GPU 资源利用 306
10.3.1 kernel 将使用多少寄存器 307
10.3.2 利用率:提高工作组的负载率 307
10.4 约减模式需要跨工作组进行同步 309
10.5 通过队列(流)进行异步计算 310
10.6 为GPU 定制并行化应用程序的策略 311
10.6.1 场景1:三维大气环境仿真 311
10.6.2 场景2:非结构化网格应用 312
10.7 进一步探索 312
10.7.1 扩展阅读 313
10.7.2 练习 314
10.8 本章小结 314
第11 章 基于指令的GPU 编程 315
11.1 为GPU
第1 章 为什么使用并行计算 3
1.1 为什么要学习并行计算 5
1.1.1 并行计算的潜在优势是什么 7
1.1.2 并行计算的注意事项 9
1.2 并行计算的基本定律 9
1.2.1 并行计算的极限:Amdahl 定律 9
1.2.2 突破并行极限:Gustafson-Barsis定律 10
1.3 并行计算如何工作 12
1.3.1 应用程序示例 13
1.3.2 当今异构并行系统的硬件模型 18
1.3.3 当今异构并行系统的应用程序模型及软件模型 21
1.4 对并行方法进行分类 24
1.5 并行策略 25
1.6 并行加速与比较加速:两种不同的衡量标准 26
1.7 你将在本书中学到哪些内容 27
1.7.1 扩展阅读 27
1.7.2 练习 28
1.8 本章小结 28
第2 章 规划并行化 29
2.1 处理新项目:准备工作 30
2.1.1 版本控制:为并行代码创建一个安全的存储库 31
2.1.2 测试套件:创建健壮、可靠的应用程序的优质步 32
2.1.3 查找和修复内存问题 40
2.1.4 提高代码的可移植性 41
2.2 概要分析:探测系统功能和应用程序性能之间的差距 42
2.3 计划:成功的基础 42
2.3.1 探索benchmark 和mini-apps 43
2.3.2 核心数据结构和代码模块化设计 43
2.3.3 算法:重新设计并行 44
2.4 实施 44
2.5 提交:高质量的打包过程 45
2.6 进一步探索 46
2.6.1 扩展阅读 46
2.6.2 练习 46
2.7 本章小结 46
第3 章 性能极限与分析 49
3.1 了解应用程序的潜在性能限制 49
3.2 了解硬件性能:基准测试 52
3.2.1 用于收集系统特征的工具 52
3.2.2 计算浮点运算的最大理论值 55
3.2.3 内存层级和理论内存带宽 55
3.2.4 带宽和浮点运算的实证测量 56
3.2.5 计算flop 和带宽之间的机器平衡 59
3.3 描述你的应用程序:分析 59
3.3.1 分析工具 60
3.3.2 处理器时钟频率和能耗的实证测量 69
3.3.3 在运行时跟踪内存 70
3.4 进一步探索 71
3.4.1 扩展阅读 71
3.4.2 练习 71
3.5 本章小结 71
第4 章 数据设计和性能模型 73
4.1 数据结构与性能:面向数据的设计 74
4.1.1 多维数组 76
4.1.2 结构数组(AoS)与数组结构(SoA) 80
4.1.3 数组结构的数组(AoSoA) 85
4.2 缓存未命中的3C:强制、容量与冲突 86
4.3 简单性能模型:案例研究 90
4.3.1 全矩阵数据表示 92
4.3.2 压缩稀疏存储表示 95
4.4 高级性能模型 98
4.5 网络消息 101
4.6 进一步探索 103
4.6.1 扩展阅读 104
4.6.2 练习 104
4.7 本章小结 104
第5 章 并行算法与模式 105
5.1 并行计算应用的算法分析 105
5.2 性能模型与算法复杂性 106
5.3 什么是并行算法 109
5.4 什么是哈希函数 110
5.5 空间哈希:一种高并行度算法 111
5.5.1 使用优质哈希进行空间网格操作 113
5.5.2 使用紧凑哈希进行空间网格操作 126
5.6 prefix sum(扫描)模式及其在并行计算中的重要性 132
5.6.1 Step-efficient 并行扫描操作 133
5.6.2 Work-efficient 并行扫描操作 134
5.6.3 用于大型数组的并行扫描操作 135
5.7 并行全局和:解决关联性问题 135
5.8 并行算法研究的未来 141
5.9 进一步探索 141
5.9.1 扩展阅读 141
5.9.2 练习 142
5.10 本章小结 142
第II 部分 CPU:并行的主力第6 章 向量化:免费的flop 145
6.1 向量及单指令多数据流(SIMD)概要 145
6.2 向量化的硬件趋势 146
6.3 向量化方法 147
6.3.1 使用优化软件库可以轻松提高性能 148
6.3.2 自动向量化:向量化加速的简单方法(大多数情况下) 148
6.3.3 通过提示来指导编译器:pragma和指令 152
6.3.4 使用向量本征库处理无法向量化的循环 157
6.3.5 大胆尝试:使用汇编代码进行向量化 162
6.4 实现更好向量化的编程风格 163
6.5 与编译器向量化相关的编译器标志 164
6.6 使用OpenMP SIMD 指令实现更好的移植性 170
6.7 进一步探索 172
6.7.1 扩展阅读 172
6.7.2 练习 172
6.8 本章小结 173
第7 章 使用OpenMP 实现并行计算 175
7.1 OpenMP 介绍 175
7.1.1 OpenMP 概念 176
7.1.2 OpenMP 简单程序示例 179
7.2 典型的OpenMP 用例:循环级OpenMP、高级OpenMP 和MPI +OpenMP 183
7.2.1 使用循环级OpenMP 进行快速并行化 184
7.2.2 使用高级OpenMP 获得更好的并行度 184
7.2.3 使用MPI + OpenMP 获得极限可扩展性 185
7.3 标准循环级OpenMP 示例 185
7.3.1 循环级OpenMP:向量加法示例 186
7.3.2 stream triad 示例 189
7.3.3 循环级OpenMP:stencil 示例 190
7.3.4 循环级示例的性能 191
7.3.5 使用OpenMP 线程的global sum的约减示例 192
7.3.6 循环级OpenMP 的潜在问题 193
7.4 OpenMP 中变量范围对结果准确性的重要性 193
7.5 函数级OpenMP:使整个函数实现线程并行 194
7.6 使用高级OpenMP 改进并行可伸缩性 196
7.6.1 如何实现高级OpenMP 197
7.6.2 实现高级OpenMP 的示例 199
7.7 使用OpenMP 混合线程及向量化 201
7.8 使用OpenMP 的高级示例 204
7.8.1 在x 和y 方向单独传递的stencil示例 204
7.8.2 使用OpenMP 线程实现kahan求和 208
7.8.3 通过线程实现的prefix scan算法 209
7.9 线程工具对健壮程序的重要性 210
7.9.1 使用Allinea/ARM MAP快速获得应用程序的高层概要文件 211
7.9.2 使用Intel Inspector 查找线程竞态条件 212
7.10 基于任务的支持算法示例 213
7.11 进一步探索 214
7.11.1 扩展阅读 214
7.11.2 练习 215
7.12 本章小结 215
第8 章 MPI:并行骨干 217
8.1 MPI 程序基础 217
8.1.1 为每个MPI 程序进行基本MPI函数调用 218
8.1.2 简单MPI 程序的编译器包装器 219
8.1.3 使用并行启动命令 219
8.1.4 MPI 程序的最小工作示例 219
8.2 用于进程间通信的发送和接收命令 221
8.3 聚合通信:MPI 的强大组件 227
8.3.1 使用barrier 来同步计时器 228
8.3.2 使用广播处理小文件输入 228
8.3.3 使用约减从所有进程中获取单个值 230
8.3.4 使用gather 在调试打印输出中排序 233
8.3.5 使用scatter 和gather 将数据发送到工作进程 234
8.4 数据并行示例 236
8.4.1 使用stream triad 来测量节点上的带宽 236
8.4.2 二维网格中的ghost cell 交换 238
8.4.3 三维stencil 计算中的ghost cell交换 244
8.5 使用高级MPI 功能来简化代码和启用优化 245
8.5.1 使用自定义MPI 数据类型来简化代码并提升性能 245
8.5.2 MPI 中的笛卡儿拓扑 250
8.5.3 ghost cell 交换变体的性能测试 255
8.6 通过联合使用MPI 和OpenMP实现极高的可扩展性 257
8.6.1 混合MPI 和OpenMP 的优势 257
8.6.2 MPI 与OpenMP 混合示例 258
8.7 进一步探索 259
8.7.1 扩展阅读 260
8.7.2 练习 260
8.8 本章小结 261
第III 部分 GPU:加速应用程序运行
第9 章 GPU 架构及概念 265
9.1 作为加速计算平台的CPU-GPU
系统 266
9.1.1 集成GPU:商业化系统中没有被充分使用的资源 267
9.1.2 独立GPU:高性能计算的主力 267
9.2 GPU 和线程引擎 268
9.2.1 使用流多处理器(或子片)作为计算单元 270
9.2.2 作为独立处理器的处理单元 270
9.2.3 每个处理单元进行多个数据操作 270
9.2.4 计算GPU flop 的理论峰值 270
9.3 GPU 内存空间的特点 272
9.3.1 计算内存带宽的理论峰值 273
9.3.2 测量GPU stream benchmark 274
9.3.3 GPU 的Roofline 性能模型 275
9.3.4 使用mixbench 性能工具为工作负载选择GPU 276
9.4 PCI 总线:CPU 与GPU 之间的数据传输桥梁 278
9.4.1 PCI 总线的理论带宽 279
9.4.2 PCI 带宽benchmark 应用程序 281
9.5 多GPU 平台和MPI 284
9.5.1 优化网络中GPU 之间的数据移动 284
9.5.2 一种比PCI 总线性能更高的替代方案 285
9.6 GPU 加速平台的潜在收益 286
9.6.1 缩短解决问题的时间 286
9.6.2 使用GPU 降低能耗 287
9.6.3 使用GPU 降低云计算成本 292
9.7 何时使用GPU 292
9.8 进一步探索 292
9.8.1 扩展阅读 293
9.8.2 练习 293
9.9 本章小结 293
第10 章 GPU 编程模型 295
10.1 GPU 编程抽象:通用框架 296
10.1.1 大规模并行处理 296
10.1.2 无法在任务之间进行协调 297
10.1.3 GPU 并行性的术语 297
10.1.4 将数据分解成独立的工作单元:NDRange 或网格 297
10.1.5 为工作组提供大小合适的工作块 300
10.1.6 通过lockstep 执行子工作组、warp 与wavefront 300
10.1.7 工作项:操作的基本单元 301
10.1.8 SIMD 或向量硬件 301
10.2 GPU 编程模型的代码结构 302
10.2.1 “Me”编程:并行kernel的概念 302
10.2.2 线程索引:将本地tile 映射到全局中 303
10.2.3 索引集 304
10.2.4 如何在GPU 编程模型中对内存资源进行寻址 305
10.3 优化GPU 资源利用 306
10.3.1 kernel 将使用多少寄存器 307
10.3.2 利用率:提高工作组的负载率 307
10.4 约减模式需要跨工作组进行同步 309
10.5 通过队列(流)进行异步计算 310
10.6 为GPU 定制并行化应用程序的策略 311
10.6.1 场景1:三维大气环境仿真 311
10.6.2 场景2:非结构化网格应用 312
10.7 进一步探索 312
10.7.1 扩展阅读 313
10.7.2 练习 314
10.8 本章小结 314
第11 章 基于指令的GPU 编程 315
11.1 为GPU
目 录内容简介
主要内容1.规划新的并行项目2.了解CPU和GPU架构上的差异3.找到性能不佳的内核和循环4.使用批处理调度来管理应用程序
比价列表价格走势







缺书网
扫码进群