第1章 概述 1
1.1 图形处理器 1
1.1.1 图形处理器的发展 3
1.1.2 图形处理器的作用 4
1.2 着色语言 5
1.2.1 图形流水线 5
1.2.2 OpenGL:流水线的一种实现 7
1.2.3 可编程图形流水线和GLSL 8
1.3 GPGPU语言 9
1.3.1 异构计算资源 9
1.3.2 统一着色器模型 10
1.3.3 CUDA 11
1.3.4 OpenCL 12
1.4 为什么选择GPGPU技术 13
1.4.1 桌上的超级计算机 13
1.4.2 从处理器结构说起 14
1.4.3 GPGPU的应用 16
1.5 几个基本概念 18
1.5.1 并行计算模型:SIMD 19
1.5.2 数据传输的瓶颈 22
1.5.3 GPGPU算法设计准则 24
1.5.4 GPGPU技术的适用范围 24
1.6 系统需求 26
1.6.1 硬件配置 26
1.6.2 软件设置 27
1.7 一个简单的例子:离散卷积 29
第2章 GLSL:一门着色语言 36
2.1 OpenGL的安装 36
2.1.1 在Windows中安装OpenGL 37
2.1.2 在Linux中安装OpenGL 37
2.1.3 在Mac OS X 中安装OpenGL 38
2.1.4 例程的开发环境 39
2.2 一个简短的OpenGL程序 40
2.2.1 编译预处理 42
2.2.2 有限状态机 42
2.2.3 回调函数 43
2.2.4 深度缓存 48
2.2.5 窗口程序的典型流程 49
2.2.6 OpenGL的图形流水线 50
2.3 第二版:替换着色器 51
2.3.1 GLSL基础 52
2.3.2 流经着色器 55
2.3.3 着色器对象 56
2.3.4 程序对象 57
2.3.5 编译和链接 58
2.3.6 ARB扩展 59
2.3.7简短的OpenGL程序(第二版) 59
2.4 第三版:与OpenGL通信 63
第3章 经典GPGPU技术 67
3.1 纹理映射等于科学计算吗 67
3.1.1 纹理映射概述 67
3.1.2 几何图元 68
3.1.3 位图与并行流水线 70
3.1.4 纹理图 73
3.1.5 纹理坐标 76
3.1.6 纹理参数 76
3.1.7 映射参数 79
3.1.8 纹理对象 79
3.1.9 纹理单元 80
3.2 经典GPGPU的理念 81
3.2.1 经典GPGPU计算流程 81
3.2.2 GPU与CPU的类比 88
3.3 纹理存储器 89
3.3.1 纹理类型和纹理格式 89
3.3.2 写入与读回纹理 90
3.3.3 使用硬件加速 94
3.4 使用GLSL加速的离散卷积 95
3.4.1 主程序通贯 95
3.4.2 清除着色器 107
3.4.3 卷积核 107
3.4.4 性能 110
3.5 经典GPGPU的优与劣 110
第4章 CUDA:流行的GPGPU语言 111
4.1 关于CUDA 111
4.1.1 聚集和散布 112
4.1.2 可扩展的编程模型 112
4.1.3 SIMT:单指令多线程 113
4.1.4 并发计算 114
4.2 准备工作 115
4.2.1 CUDA的安装和编译 116
4.2.2 检查硬件配置 122
4.3 第一个CUDA程序 129
4.3.1 CUTIL内联库 129
4.3.2 线程组的结构 130
4.3.3 分配存储空间 131
4.3.4 定义内核 132
4.3.5 主机/设备的数据复制 133
4.3.6 完整的程序 133
4.3.7 二维的block 136
4.4 CUDA的基本概念 137
4.4.1 内核 137
4.4.2 线程 139
4.4.3 存储器 140
4.5 计算能力 150
4.5.1 计算能力1.x 151
4.5.2 计算能力2.0 151
4.6 计算模式 153
4.6.1 异步并发 154
4 6.2 流 154
第5章 CUDA内核优化实践 157
5.1 实现缩减内核 157
5.1.1 用经典GPGPU方法来实现 157
5.1.2 用CUDA来实现 158
5.1.3 运行计时 160
5.2 并行缩减 163
5.2.1 存储器带宽 163
5.2.2 分组缩减 164
5.3 科学使用设备存储器 168
5.4 大规模并行缩减 170
5.4.1 增加并行计算规模 170
5.4.2 最优的线程配置 173
5.5 启用共享存储器 174
5.5.1 在多处理器上求和 174
5.5.2 缩减树 176
5.5.3 避免共享存储器的bank冲突 178
5.6 指令开销 182
5.6.1 控制指令 183
5.6.2 同步指令 184
5.6.3 算数指令 187
5.7 nvcc编译器 189
5.7.1 常用参数 190
5.7.2 查看执行配置 190
5.7.3 全局存储器片上缓存 191
5.7.4 限制使用寄存器 191
5.7.5 本地存储器 191
5.7.6 数据精度 192
5.8 资源占用率 193
5.8.1 Compute Visual Profiler统计资源占用率 194
5.8.2 CUDA资源占用率计算器 194
5.8.3 提高资源占用率 195
5.9 小结 196
第6章 CUDA与纹理映射 197
6.1 CUDA的纹理存储器 197
6.1.1 纹理存储器与全局存储器 197
6.1.2 线性存储器和CUDA数组 198
6.2 纹理引用 198
6.3 纹理拾取 199
6.3.1 纹理坐标 200
6.3.2 纹理寻址 200
6.3.3 纹理滤波 200
6.4 CUDA数组 202
6.5 写入与读回纹理 203
6.6 用CUDA加速的离散卷积 206
第7章 关于CUDA的更多 211
7.1 与C++集成 211
7.1.1 CUDA SDK里的cppIntegration示例 211
7.1.2 CuPP工具 212
7.1.3 一个简易的集成框架 213
7.2 CUDA-GDB调试器 218
7.3 仿真模式 223
7.4 有用的CUDA程序库 224
7.4.1 官方程序库 224
7.4.2 其他CUDA程序库 226
7.4.3 CUDA软件开发包 228
7.4.4 CUDA实用程序库 231
7.5 多GPU系统 232
7.5.1 选取一个GPU 234
7.5.2 SLI技术和CUDA 234
7.5.3 同时使用多个GPU 235
7.5.4 多用户多GPU系统 242
7.6 CUDA语言绑定 243
7.6.1 MATLAB 243
7.6.2 IDL 246
7.6.3 Python 247
7.6.4 Fortran 248
7.6 5 Java 249
7.6.6 .NET 250
第8章 OpenCL:跨平台的解决方案 252
8.1 关于OpenCL 252
8.1.1 OpenCL的平台无关性 253
8.1.2 OpenCL与其他GPGPU语言 254
8.1.3 安装和编译 254
8.2 准备工作 256
8.2.1 收集错误信息 256
8.2.2 检查计算平台 257
8.3 OpenCL的计算架构 261
8.3.1 平台模型 261
8.3.2 执行模型 262
8.3.3 存储器模型 266
8.3.4 编程模型 268
8.4 OpenCL C 269
8.4.1 内建数据类型 269
8.4.2 向量 271
8.4.3 限定符 273
8.4.4 内建函数 274
8.4.5 预处理指令:#pragma 276
8.5 OpenCL计算流程 276
8.5.1 初始化 276
8.5.2 创建内核 277
8.5.3 主机/设备数据传输 279
8.5.4 执行内核 279
8.5.5 释放对象 280
8.5.6 总结 280
8.6 编程实践 280
8.6.1 完整的平方程序 280
8.6.2 内核计时 284
8.6.3 Compute Visual Profiler 286
8.7 API的C++绑定 286
8.7.1 简介 286
8.7.2 用法举例 287
8.8 OpenCL与HPC 289
8.8.1 OpenCL开发软件 289
8.8.2 OpenCL的语言绑定 289
8.8.3 OpenCL库 290
8.8.4 OpenCL与多GPU系统 290
8.9 OpenCL与CUDA 291
8.9.1 概念类比 291
8.9.2 限定符类比 291
8.9.3 线程索引类比 292
8.9.4 与CUDA驱动程序API相关的类比 292
附录 294
附录A 计时类 294
附录B 文本读取类 296
附录C 内存分配类 298
附录D 枚举变量cudaError的元素 301
附录E 结构体cudaDeviceProp的成员 303
附录F 支持CUDA的GPU及其计算能力等级 304
附录G 不同计算能力等级的特性 306
附录H 多GPU框架:GPUWorker 308
附录I 缩略语表 319
参考文献 321