并行计算与高性能计算

并行计算与高性能计算
分享
扫描下方二维码分享到微信
打开微信,点击右上角”+“,
使用”扫一扫“即可将网页分享到朋友圈。
2022-07
版次: 1
ISBN: 9787302607373
定价: 139.00
装帧: 其他
开本: 16开
纸张: 胶版纸
21人买过
  • 主要内容 ●规划新的并行项目 ●了解CPU和GPU架构上的差异 ●找到性能不佳的内核和循环 ●使用批处理调度来管理应用程序 Robert Robey在洛斯阿拉莫斯国家实验室工作,30多年来一直活跃在并行计算领域。Yuliana Zamora目前是芝加哥大学的博士生及Siebel学者,曾在许多国家会议上讲授现代硬件编程技术。 第Ⅰ部分 并行计算介绍

    第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 实现应用编译指令和pragma 的过程      316

    11.2 OpenACC:在GPU 上运行的最简单方法    317

    11.2.1 编译OpenACC 代码     319

    11.2.2 OpenACC 中用于加速计算的并行计算区域    320

    11.2.3 使用指令减少CPU 和GPU之间的数据移动   325

    11.2.4 优化GPU kernel   329

    11.2.5 stream triad 性能结果的总结 334

    11.2.6 高级OpenACC 技术     335

    11.3 OpenMP:加速器领域的重量级选手    337

    11.3.1 编译OpenMP 代码 337

    11.3.2 使用OpenMP 在GPU 上生成并行工作  339

    11.3.3 使用OpenMP 创建数据区域来控制到GPU 的数据移动  342

    11.3.4 为GPU 优化OpenMP    346

    11.3.5 用于GPU 的高级OpenMP  350

    11.4 进一步探索    353

    11.4.1 扩展阅读  353

    11.4.2 练习     354

    11.5 本章小结     355

    第12 章 GPU 语言:深入了解基础知识    357

    12.1 原生GPU 编程语言的特性   358

    12.2 CUDA 和HIP GPU 语言:底层性能选项  359

    12.2.1 编写和构建第一个CUDA应用程序  360

    12.2.2 CUDA 的约减kernel:事情变得复杂  367

    12.2.3 Hipifying CUDA 代码    372

    12.3 OpenCL:用于可移植的开源GPU 语言     375

    12.3.1 编写和构建第一个OpenCL应用程序  376

    12.3.2 OpenCL 中的约减  381

    12.4 SYCL:一个成为主流的实验性C  实现     384

    12.5 性能可移植性的高级语言    387

    12.5.1 Kokkos:性能可移植性生态系统  387

    12.5.2 RAJA 提供更具适应性的性能可移植性层     390

    12.6 进一步探索    392

    12.6.1 扩展阅读  392

    12.6.2 练习    393

    12.7 本章小结     393

    第13 章 GPU 配置分析及工具 395

    13.1 分析工具概要  395

    13.2 如何选择合适的工作流 396

    13.3 问题示例:浅水仿真  397

    13.4 分析工作流的示例    400

    13.4.1 运行浅水应用程序 400

    13.4.2 分析CPU 代码来制定行动计划  402

    13.4.3 为实施步骤添加OpenACC计算指令  403

    13.4.4 添加数据移动指令 405

    13.4.5 通过引导分析获取改进建议 406

    13.4.6 强大的辅助开发工具:NVIDIA Nsight 工具套件   408

    13.4.7 用于AMD GPU 生态系统的CodeXL   409

    13.5 专注于重要指标     409

    13.5.1 利用率:是否有足够的工作量   410

    13.5.2 发布效率:你的warp 是否经常停滞?     410

    13.5.3 获得带宽  411

    13.6 使用容器和虚拟机来提供备用工作流      411

    13.6.1 将Docker 容器作为解决方案      411

    13.6.2 使用VirtualBox 虚拟机   413

    13.7 移入云端:提供灵活和可扩展能力     415

    13.8 进一步探索    415

    13.8.1 扩展阅读  415

    13.8.2 练习    416

    13.9 本章小结     416

    第Ⅳ部分 高性能计算生态系统

    第14 章 关联性:与kernel 休战     419

    14.1 为什么关联性很重要  420

    14.2 探索架构     421

    14.3 OpenMP 的线程关联  422

    14.4 进程关联性与MPI    429

    14.4.1 OpenMPI 的默认进程放置  429

    14.4.2 进行控制:在OpenMPI 中指定进程放置的基本技术     430

    14.4.3 关联性不仅仅是进程绑定:全面讨论  434

    14.5 MPI OpenMP 的关联性     436

    14.6 从命令行控制关联性  440

    14.6.1 使用hwloc-bind 分配关联性 440

    14.6.2 使用likwid-pin: likwid 工具套件中的关联工具  441

    14.7 展望未来:在运行时设置和更改关联性    443

    14.7.1 在可执行文件中设置关联性 443

    14.7.2 在运行时更改进程关联性  445

    14.8 进一步探索    447

    14.8.1 扩展阅读  447

    14.8.2 练习    448

    14.9 本章小结     449

    第15 章 批处理调度器:为混乱带来秩序    451

    15.1 无管理系统所带来的混乱    452

    15.2 如何顺利地在繁忙的集群中部署任务     452

    15.2.1 繁忙集群中的批处理系统布局    453

    15.2.2 如何合理地在繁忙的集群和HPC 站点上运行任务:HPC 中的推荐做法     453

    15.3 提交第一个批处理脚本 454

    15.4 为长时间运行的作业设定自动重启     459

    15.5 在批处理脚本中指定依赖项  463

    15.6 进一步探索    465

    15.6.1 扩展阅读  465

    15.6.2 练习    465

    15.7 本章小结     466

    第16 章 并行环境的文件操作  467

    16.1 高性能文件系统的组成部分  467

    16.2 标准文件操作:并行到串行(parallel-to-serial)接口  468

    16.3 在并行环境中使用MPI

    文件操作(MPI-IO)    469

    16.4 HDF5 具有自我描述功能,可更好地管理数据   477

    16.5 其他并行文件软件包  485

    16.6 并行文件系统:硬件接口    485

    16.6.1 并行文件设置    485

    16.6.2 适用于所有文件系统的通用提示    489

    16.6.3 特定文件系统的提示    490

    16.7 进一步探索    493

    16.7.1 扩展阅读  493

    16.7.2 练习    494

    16.8 本章小结     494

    第17 章 用于编写优质代码的工具和资源    495

    17.1 版本控制系统:一切从这里开始    497

    17.1.1 分布式版本控制更适合全局协作    498

    17.1.2 通过集中版本控制来简化操作并提高代码安全   498

    17.2 用于跟踪代码性能的计时器例程    499

    17.3 分析器:不去衡量就无法提升 500

    17.3.1 日常使用的基于文本的分析器   501

    17.3.2 用于快速识别瓶颈的高级分析器   502

    17.3.3 使用中级分析器来指导应用程序开发  502

    17.3.4 通过详细分析器了解硬件性能的细节信息     504

    17.4 benchmark 和mini-apps:了解系统性能的窗口     504

    17.4.1 使用benchmark 测量系统性能特征  504

    17.4.2 通过mini-apps 提供应用程序的视角   505

    17.5 为健壮的应用程序检测及修复内存错误     507

    17.5.1 valgrind Memcheck:备用开源方案  507

    17.5.2 使用Dr. Memory 诊断内存问题  507

    17.5.3 对于要求严苛的应用程序使用商业内存检测工具   509

    17.5.4 使用基于编译器的内存工具来简化操作  509

    17.5.5 通过Fence-post 检查器来检测越界内存访问    510

    17.5.6 GPU 应用程序所使用的内存工具  511

    17.6 用于检测竞态条件的线程检查器      512

    17.6.1 Intel Inspector:带有GUI 的竞态条件检测工具 512

    17.6.2 Archer:一个基于文本的检测竞态条件的工具   512

    17.7 Bug-busters:用于消除bug 的调试器      514

    17.7.1 在HPC 站点中广泛使用的TotalView 调试器  514

    17.7.2 DDT:另一种在HPC 站点广泛使用的调试器    514

    17.7.3 Linux 调试器:为本地开发需求提供免费的替代方案  515

    17.7.4 通过GPU 调试器消除GPU bug  515

    17.8 文件操作分析  516

    17.9 包管理器:你的个人系统管理员      519

    17.9.1 macOS 的包管理器 519

    17.9.2 Windows 包管理器 519

    17.9.3 Spack 包管理器:用于高性能计算的包管理器  519

    17.10 模块:加载专门的工具链   520

    17.10.1 TCL modules:用于加载软件工具链的原始模块系统  522

    17.10.2 Lmod:基于Lua 的替代模块实现   523

    17.11 思考与练习   523

    17.12 本章小结    523

    附录A 参考资料     (可从配书网站下载)

    附录B 习题答案     (可从配书网站下载)
  • 内容简介:
    主要内容 ●规划新的并行项目 ●了解CPU和GPU架构上的差异 ●找到性能不佳的内核和循环 ●使用批处理调度来管理应用程序
  • 作者简介:
    Robert Robey在洛斯阿拉莫斯国家实验室工作,30多年来一直活跃在并行计算领域。Yuliana Zamora目前是芝加哥大学的博士生及Siebel学者,曾在许多国家会议上讲授现代硬件编程技术。
  • 目录:
    第Ⅰ部分 并行计算介绍

    第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 实现应用编译指令和pragma 的过程      316

    11.2 OpenACC:在GPU 上运行的最简单方法    317

    11.2.1 编译OpenACC 代码     319

    11.2.2 OpenACC 中用于加速计算的并行计算区域    320

    11.2.3 使用指令减少CPU 和GPU之间的数据移动   325

    11.2.4 优化GPU kernel   329

    11.2.5 stream triad 性能结果的总结 334

    11.2.6 高级OpenACC 技术     335

    11.3 OpenMP:加速器领域的重量级选手    337

    11.3.1 编译OpenMP 代码 337

    11.3.2 使用OpenMP 在GPU 上生成并行工作  339

    11.3.3 使用OpenMP 创建数据区域来控制到GPU 的数据移动  342

    11.3.4 为GPU 优化OpenMP    346

    11.3.5 用于GPU 的高级OpenMP  350

    11.4 进一步探索    353

    11.4.1 扩展阅读  353

    11.4.2 练习     354

    11.5 本章小结     355

    第12 章 GPU 语言:深入了解基础知识    357

    12.1 原生GPU 编程语言的特性   358

    12.2 CUDA 和HIP GPU 语言:底层性能选项  359

    12.2.1 编写和构建第一个CUDA应用程序  360

    12.2.2 CUDA 的约减kernel:事情变得复杂  367

    12.2.3 Hipifying CUDA 代码    372

    12.3 OpenCL:用于可移植的开源GPU 语言     375

    12.3.1 编写和构建第一个OpenCL应用程序  376

    12.3.2 OpenCL 中的约减  381

    12.4 SYCL:一个成为主流的实验性C  实现     384

    12.5 性能可移植性的高级语言    387

    12.5.1 Kokkos:性能可移植性生态系统  387

    12.5.2 RAJA 提供更具适应性的性能可移植性层     390

    12.6 进一步探索    392

    12.6.1 扩展阅读  392

    12.6.2 练习    393

    12.7 本章小结     393

    第13 章 GPU 配置分析及工具 395

    13.1 分析工具概要  395

    13.2 如何选择合适的工作流 396

    13.3 问题示例:浅水仿真  397

    13.4 分析工作流的示例    400

    13.4.1 运行浅水应用程序 400

    13.4.2 分析CPU 代码来制定行动计划  402

    13.4.3 为实施步骤添加OpenACC计算指令  403

    13.4.4 添加数据移动指令 405

    13.4.5 通过引导分析获取改进建议 406

    13.4.6 强大的辅助开发工具:NVIDIA Nsight 工具套件   408

    13.4.7 用于AMD GPU 生态系统的CodeXL   409

    13.5 专注于重要指标     409

    13.5.1 利用率:是否有足够的工作量   410

    13.5.2 发布效率:你的warp 是否经常停滞?     410

    13.5.3 获得带宽  411

    13.6 使用容器和虚拟机来提供备用工作流      411

    13.6.1 将Docker 容器作为解决方案      411

    13.6.2 使用VirtualBox 虚拟机   413

    13.7 移入云端:提供灵活和可扩展能力     415

    13.8 进一步探索    415

    13.8.1 扩展阅读  415

    13.8.2 练习    416

    13.9 本章小结     416

    第Ⅳ部分 高性能计算生态系统

    第14 章 关联性:与kernel 休战     419

    14.1 为什么关联性很重要  420

    14.2 探索架构     421

    14.3 OpenMP 的线程关联  422

    14.4 进程关联性与MPI    429

    14.4.1 OpenMPI 的默认进程放置  429

    14.4.2 进行控制:在OpenMPI 中指定进程放置的基本技术     430

    14.4.3 关联性不仅仅是进程绑定:全面讨论  434

    14.5 MPI OpenMP 的关联性     436

    14.6 从命令行控制关联性  440

    14.6.1 使用hwloc-bind 分配关联性 440

    14.6.2 使用likwid-pin: likwid 工具套件中的关联工具  441

    14.7 展望未来:在运行时设置和更改关联性    443

    14.7.1 在可执行文件中设置关联性 443

    14.7.2 在运行时更改进程关联性  445

    14.8 进一步探索    447

    14.8.1 扩展阅读  447

    14.8.2 练习    448

    14.9 本章小结     449

    第15 章 批处理调度器:为混乱带来秩序    451

    15.1 无管理系统所带来的混乱    452

    15.2 如何顺利地在繁忙的集群中部署任务     452

    15.2.1 繁忙集群中的批处理系统布局    453

    15.2.2 如何合理地在繁忙的集群和HPC 站点上运行任务:HPC 中的推荐做法     453

    15.3 提交第一个批处理脚本 454

    15.4 为长时间运行的作业设定自动重启     459

    15.5 在批处理脚本中指定依赖项  463

    15.6 进一步探索    465

    15.6.1 扩展阅读  465

    15.6.2 练习    465

    15.7 本章小结     466

    第16 章 并行环境的文件操作  467

    16.1 高性能文件系统的组成部分  467

    16.2 标准文件操作:并行到串行(parallel-to-serial)接口  468

    16.3 在并行环境中使用MPI

    文件操作(MPI-IO)    469

    16.4 HDF5 具有自我描述功能,可更好地管理数据   477

    16.5 其他并行文件软件包  485

    16.6 并行文件系统:硬件接口    485

    16.6.1 并行文件设置    485

    16.6.2 适用于所有文件系统的通用提示    489

    16.6.3 特定文件系统的提示    490

    16.7 进一步探索    493

    16.7.1 扩展阅读  493

    16.7.2 练习    494

    16.8 本章小结     494

    第17 章 用于编写优质代码的工具和资源    495

    17.1 版本控制系统:一切从这里开始    497

    17.1.1 分布式版本控制更适合全局协作    498

    17.1.2 通过集中版本控制来简化操作并提高代码安全   498

    17.2 用于跟踪代码性能的计时器例程    499

    17.3 分析器:不去衡量就无法提升 500

    17.3.1 日常使用的基于文本的分析器   501

    17.3.2 用于快速识别瓶颈的高级分析器   502

    17.3.3 使用中级分析器来指导应用程序开发  502

    17.3.4 通过详细分析器了解硬件性能的细节信息     504

    17.4 benchmark 和mini-apps:了解系统性能的窗口     504

    17.4.1 使用benchmark 测量系统性能特征  504

    17.4.2 通过mini-apps 提供应用程序的视角   505

    17.5 为健壮的应用程序检测及修复内存错误     507

    17.5.1 valgrind Memcheck:备用开源方案  507

    17.5.2 使用Dr. Memory 诊断内存问题  507

    17.5.3 对于要求严苛的应用程序使用商业内存检测工具   509

    17.5.4 使用基于编译器的内存工具来简化操作  509

    17.5.5 通过Fence-post 检查器来检测越界内存访问    510

    17.5.6 GPU 应用程序所使用的内存工具  511

    17.6 用于检测竞态条件的线程检查器      512

    17.6.1 Intel Inspector:带有GUI 的竞态条件检测工具 512

    17.6.2 Archer:一个基于文本的检测竞态条件的工具   512

    17.7 Bug-busters:用于消除bug 的调试器      514

    17.7.1 在HPC 站点中广泛使用的TotalView 调试器  514

    17.7.2 DDT:另一种在HPC 站点广泛使用的调试器    514

    17.7.3 Linux 调试器:为本地开发需求提供免费的替代方案  515

    17.7.4 通过GPU 调试器消除GPU bug  515

    17.8 文件操作分析  516

    17.9 包管理器:你的个人系统管理员      519

    17.9.1 macOS 的包管理器 519

    17.9.2 Windows 包管理器 519

    17.9.3 Spack 包管理器:用于高性能计算的包管理器  519

    17.10 模块:加载专门的工具链   520

    17.10.1 TCL modules:用于加载软件工具链的原始模块系统  522

    17.10.2 Lmod:基于Lua 的替代模块实现   523

    17.11 思考与练习   523

    17.12 本章小结    523

    附录A 参考资料     (可从配书网站下载)

    附录B 习题答案     (可从配书网站下载)
查看详情
相关图书 / 更多
并行计算与高性能计算
并行程序设计:概念与实践
[德]贝蒂尔·施密特(Bertil Schmidt) 著;张常有 、吴长茂、解庆春 译
并行计算与高性能计算
并行编程
张杨
并行计算与高性能计算
并行计算导论/人工智能与大数据技术丛书
雷向东、雷振阳、龙军 著
并行计算与高性能计算
并行离群数据挖掘及应用
李俊丽 著
并行计算与高性能计算
并行数据挖掘及性能优化:关联规则与数据相关性分析
荀亚玲 著
并行计算与高性能计算
并行编程实战——基于C#8和.NETCore3
[印]沙克蒂·坦沃 著;马琳琳 译
并行计算与高性能计算
并行计算的编程模型
[美]帕万·巴拉吉(Pavan Balaji)
并行计算与高性能计算
并行化河流数学模型研发及应用
李健、霍军军 著
并行计算与高性能计算
并行多核体系结构基础
[美]汤孟岩(Yan Solihin)
并行计算与高性能计算
并行计算机体系结构(第2版)
陈国良
并行计算与高性能计算
并行书系 雕光刻影 皮影雕刻巨匠汪天稳 传承传统文化 匠人精神在中国
张欣 著
并行计算与高性能计算
并行编程原理与程序设计
何兵寿;宋鹏;刘颖