第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.2 GPGPU:一个中间步骤 27
2.3 GPU计算 28
2.3.1可扩展的GPU 29
2.3.2发展近况 29
2.3.3未来发展趋势 30
参考文献与课外阅读 30
第3章 CUDA简介 35
3.1数据并行性 36
3.2 CUDA的程序结构 37
3.3向量加法kernel函数 39
3.4设备全局存储器与数据传输 41
3.5 kemel函数与线程 46
3.6小结 50
3.6.1函数声明 50
3.6.2启动kemel函数 50
3.6.3预定义变量 51
3.6.4运行时API 51
3.7习题 51
参考文献 53
第4章 数据并行执行模型 55
4.1 CUDA的线程组织 56
4.2线程与多维数据的映射 59
4.3矩阵乘法——一个更加复杂的kemel函数 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.2 CUDA设备存储器的类型 83
5.3减少全局存储器流量的一种策略 89
5.4分块矩阵乘法的kemel函数 93
5.5存储器——限制并行性的一个因素 98
5.6小结 100
5.7习题 101
第6章 性能优化 103
6.1 WARP和线程执行 104
6.2全局存储器的带宽 111
6.3执行资源的动态划分 118
6.4指令混合和线程粒度 120
6.5小结 121
6.6习题 121
参考文献 124
第7章 浮点运算 127
7.1浮点格式 128
7.1.1 M的规范化表示 128
7.1.2 E的余码表示 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.2 kernel函数简单的实现方案 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.4 kemel函数 250
14.5设备管理和启动kemel 251
14.6 OpenCL中的静电势图谱 254
14.7小结 258
14.8习题 258
参考文献 259
第15章 OpenACC并行编程 261
15.1 OpenACC与CUDA C的比较 261
15.2执行模型 263
15.3存储器模型 265
15.4基本的OpenACC程序 266
15.4.1并行构造 266
15.4.2循环构造 267
15.4.3 kernels构造 272
15.4.4数据管理 275
15.4.5数据构造 276
15.4.6异步计算和数据传输 278
15.5 OpenACC的发展方向 279
15.6习题 280
第16章 Thrust:一个面向效率的CUDA编程库 281
16.1背景简介 282
16.2动机 284
16.3 Thrust的基本特性 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.1 CUDA FORTRAN和CUDA C的区别 300
17.2第一个CUDA FORTRAN程序 301
17.3 CUDA FORTRAN中的多维数组 303
17.4用通用接口重载主机/设备端例程 304
17.5通过iso_c_binding调用CUDA C 307
17.6 kemel循环指令和归约操作 309
17.7动态共享存储器 310
17.8异步数据传输 311
17.9编译和性能剖析 316
17.10在CUDA FORTRAN中调用Thrust 317
17.11习题 321
第18章 C+ AMP简介 323
18.1 C++ AMP核心特性 324
18.2 C++ AMP执行模式详解 329
18.2.1显式和隐式的数据复制 330
18.2.2异步操作 331
18.2.3本节小结 333
18.3加速器管理 333
18.4分块执行 335
18.5 C++ AMP图形特性 338
18.6小结 340
18.7习题 341
第19章 异构集群编程 343
19.1背景简介 344
19.2运行示例 344
19.3 MPI基础 346
19.4 MPI点对点通信模型 348
19.5重叠计算和通信 355
19.6 MPI集合通信模型 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.2 API错误和启动失败 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.4 ECC错误 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.3 kemel函数执行控制过程的演变 389
21.3.1 kemel函数内部的函数调用 389
21.3.2 kemel函数中的异常处理 390
21.3.3多个kemel函数的同步执行 390
21.3.4可中断的kemel函数 391
21.4内核的性能 391
21.4.1双精度的速度 391
21.4.2更好的控制流效率 392
21.5编程环境 392
21.6美好前景 392
参考文献 393
附录A 矩阵乘法主机版的源代码 395
附录B GPU的计算能力 407