第1章 基于CUDA的异构并行计算 1
1.1并行计算 1
1.1.1串行编程和并行编程 2
1.1.2并行性 3
1.1.3计算机架构 4
1.2异构计算 6
1.2.1异构架构 7
1.2.2异构计算范例 9
1.2.3 CUDA:一种异构计算平台 10
1.3用GPU输出Hello World 12
1.4使用CUDA C编程难吗 15
1.5总结 16
1.6习题 16
第2章CUDA编程模型 18
2.1 CUDA编程模型概述 18
2.1.1 CUDA编程结构 19
2.1.2内存管理 20
2.1.3线程管理 24
2.1.4启动一个CUDA核函数 29
2.1.5编写核函数 30
2.1.6验证核函数 31
2.1.7处理错误 32
2.1.8编译和执行 32
2.2给核函数计时 35
2.2.1用CPU计时器计时 35
2.2.2用nvprof工具计时 39
2.3组织并行线程 40
2.3.1使用块和线程建立矩阵索引 40
2.3.2使用二维网格和二维块对矩阵求和 44
2.3.3使用一维网格和一维块对矩阵求和 47
2.3.4使用二维网格和一维块对矩阵求和 48
2.4设备管理 50
2.4.1使用运行时API查询GPU信息 50
2.4.2确定最优GPU 53
2.4.3使用nvidia-smi查询GPU信息 53
2.4.4在运行时设置设备 54
2.5总结 54
2.6习题 55
第3章CUDA执行模型 56
3.1 CUDA执行模型概述 56
3.1.1 GPU架构概述 57
3.1.2 Fermi架构 59
3.1.3 Kepler架构 61
3.1.4配置文件驱动优化 65
3.2理解线程束执行的本质 67
3.2.1线程束和线程块 67
3.2.2线程束分化 69
3.2.3资源分配 74
3.2.4延迟隐藏 76
3.2.5占用率 78
3.2.6同步 81
3.2.7可扩展性 82
3.3并行性的表现 83
3.3.1用nvprof检测活跃的线程束 84
3.3.2用nvprof检测内存操作 85
3.3.3增大并行性 86
3.4避免分支分化 88
3.4.1并行归约问题 88
3.4.2并行归约中的分化 89
3.4.3改善并行归约的分化 93
3.4.4交错配对的归约 95
3.5展开循环 97
3.5.1展开的归约 97
3.5.2展开线程的归约 99
3.5.3完全展开的归约 101
3.5.4模板函数的归约 102
3.6动态并行 104
3.6.1嵌套执行 105
3.6.2在GPU上嵌套Hello World 106
3.6.3嵌套归约 109
3.7总结 113
3.8习题 113
第4章 全局内存 115
4.1 CUDA内存模型概述 115
4.1.1内存层次结构的优点 116
4.1.2 CUDA内存模型 117
4.2内存管理 124
4.2.1内存分配和释放 124
4.2.2内存传输 125
4.2.3固定内存 127
4.2.4零拷贝内存 128
4.2.5统一虚拟寻址 133
4.2.6统一内存寻址 134
4.3内存访问模式 135
4.3.1对齐与合并访问 135
4.3.2全局内存读取 137
4.3.3全局内存写入 145
4.3.4结构体数组与数组结构体 147
4.3.5性能调整 151
4.4核函数可达到的带宽 154
4.4.1内存带宽 154
4.4.2矩阵转置问题 155
4.5使用统一内存的矩阵加法 167
4.6总结 171
4.7习题 172
第5章 共享内存和常量内存 174
5.1 CUDA共享内存概述 174
5.1.1共享内存 175
5.1.2共享内存分配 176
5.1.3共享内存存储体和访问模式 176
5.1.4配置共享内存量 181
5.1.5同步 183
5.2共享内存的数据布局 185
5.2.1方形共享内存 185
5.2.2矩形共享内存 193
5.3减少全局内存访问 199
5.3.1使用共享内存的并行归约 199
5.3.2使用展开的并行归约 202
5.3.3使用动态共享内存的并行归约 204
5.3.4有效带宽 205
5.4合并的全局内存访问 205
5.4.1基准转置内核 205
5.4.2使用共享内存的矩阵转置 207
5.4.3使用填充共享内存的矩阵转置 210
5.4.4使用展开的矩阵转置 211
5.4.5增大并行性 214
5.5常量内存 215
5.5.1使用常量内存实现一维模板 215
5.5.2与只读缓存的比较 217
5.6线程束洗牌指令 219
5.6.1线程束洗牌指令的不同形式 220
5.6.2线程束内的共享数据 222
5.6.3使用线程束洗牌指令的并行归约 226
5.7总结 227
5.8习题 228
第6章 流和并发 230
6.1流和事件概述 231
6.1.1 CUDA流 231
6.1.2流调度 234
6.1.3流的优先级 235
6.1.4 CUDA事件 235
6.1.5流同步 237
6.2并发内核执行 240
6.2.1非空流中的并发内核 240
6.2.2 Fermi GPU上的虚假依赖关系 242
6.2.3使用OpenMP的调度操作 244
6.2.4用环境变量调整流行为 245
6.2.5 GPU资源的并发限制 246
6.2.6默认流的阻塞行为 247
6.2.7创建流间依赖关系 248
6.3重叠内核执行和数据传输 249
6.3.1使用深度优先调度重叠 249
6.3.2使用广度优先调度重叠 252
6.4重叠GPU和CPU执行 254
6.5流回调 255
6.6总结 256
6.7习题 257
第7章 调整指令级原语 258
7.1 CUDA指令概述 259
7.1.1浮点指令 259
7.1.2内部函数和标准函数 261
7.1.3原子操作指令 262
7.2程序优化指令 264
7.2.1单精度与双精度的比较 264
7.2.2标准函数与内部函数的比较 266
7.2.3了解原子指令 272
7.2.4综合范例 277
7.3总结 279
7.4习题 280
第8章GPU加速库和OpenACC 281
8.1 CUDA库概述 282
8.1.1 CUDA库支持的作用域 283
8.1.2通用的CUDA库工作流 283
8.2 cuSPARSE库 285
8.2.1 cuSPARSE数据存储格式 286
8.2.2用cuSPARSE进行格式转换 289
8.2.3 cuSPARSE功能示例 289
8.2.4 cuSPARSE发展中的重要主题 291
8.2.5 cuSPARSE小结 291
8.3 cuBLAS库 292
8.3.1管理cuBLAS数据 293
8.3.2 cuBLAS功能示例 294
8.3.3 cuBLAS发展中的重要主题 295
8.3.4 cuBLAS小结 296
8.4 cuFFT库 296
8.4.1使用cuFFT API 296
8.4.2 cuFFT功能示例 298
8.4.3 cuFFT小结 299
8.5 cuRAND库 299
8.5.1拟随机数或伪随机数的选择 299
8.5.2 cuRAND库概述 300
8.5.3 cuRAND介绍 303
8.5.4 cuRAND发展中的重要主题 306
8.6 CUDA 6.0中函数库的介绍 307
8.6.1 Drop-In库 307
8.6.2多GPU库 308
8.7 CUDA函数库的性能研究 310
8.7.1 cuSPARSE与MKL的比较 310
8.7.2 cuBLAS与MKL BLAS的比较 311
8.7.3 cuFFT与FFTW及MKL的比较 311
8.7.4 CUDA库性能小结 312
8.8 OpenACC的使用 312
8.8.1 OpenACC计算指令的使用 315
8.8.2 OpenACC数据指令的使用 321
8.8.3 OpenACC运行时API 325
8.8.4 OpenACC和CUDA库的结合 327
8.8.5 OpenACC小结 328
8.9总结 329
8.10习题 329
第9章多GPU编程 331
9.1从一个GPU到多GPU 332
9.1.1在多 GPU上执行 333
9.1.2点对点通信 334
9.1.3多GPU间的同步 335
9.2多GPU间细分计算 336
9.2.1在多设备上分配内存 336
9.2.2单主机线程分配工作 337
9.2.3编译和执行 337
9.3多GPU上的点对点通信 338
9.3.1实现点对点访问 338
9.3.2点对点的内存复制 339
9.3.3统一虚拟寻址的点对点内存访问 341
9.4多GPU上的有限差分 342
9.4.1二维波动方程的模板计算 342
9.4.2多GPU程序的典型模式 343
9.4.3多GPU上的二维模板计算 344
9.4.4重叠计算与通信 347
9.4.5编译和执行 348
9.5跨GPU集群扩展应用程序 350
9.5.1 CPU到CPU的数据传输 351
9.5.2使用传统MPI在GPU和GPU间传输数据 353
9.5.3使用CUDA-aware MPI进行GPU到GPU的数据传输 356
9.5.4使用CUDA-aware MPI进行节点内GPU到GPU的数据传输 357
9.5.5调整消息块大小 358
9.5.6使用GPUDirect RDMA技术进行GPU到GPU的数据传输 359
9.6总结 361
9.7习题 362
第10章 程序实现的注意事项 364
10.1 CUDA C的开发过程 364
10.1.1 APOD开发周期 365
10.1.2优化因素 367
10.1.3 CUDA代码编译 370
10.1.4 CUDA错误处理 373
10.2配置文件驱动优化 374
10.2.1使用nvprof寻找优化因素 375
10.2.2使用nvvp指导优化 379
10.2.3 NVIDIA工具扩展 381
10.3 CUDA调试 383
10.3.1内核调试 383
10.3.2内存调试 390
10.3.3调试小结 395
10.4将C程序移植到CUDA C的案例研究 396
10.4.1评估crypt 396
10.4.2并行crypt 397
10.4.3优化crypt 398
10.4.4部署crypt 404
10.4.5移植crypt小结 407
10.5总结 407
10.6习题 407
附录 推荐阅读 409