1、CUDA C编程权威指南编程权威指南 演讲人2020-11-2101技术审校者简介技术审校者简介021 基于CUDA的异构并行计算1 1 基于基于CUDACUDA的异构并行计算的异构并行计算1.1 并行计算1.2 异构计算1.3 用GPU输出Hello World1.6 习题1.5 总结1.4 使用CUDA C编程难吗LOGOLOGOhttps:/1 1 基于基于CUDACUDA的异构并行的异构并行计算计算1.1 并行计算1.1.1 串行编程和并行编程1.1.2 并行性1.1.3 计算机架构1 1 基于基于CUDACUDA的异构并行计算的异构并行计算1.2 异构计算CBA1.2.1 异构架构1
2、.2.2 异构计算范例1.2.3 CUDA:一种异构计算平台032 CUDA编程模型2 CUDA2 CUDA编程模型编程模型010103032.1 CUDA编程模型概述2.2 给核函数计时2.3 组织并行线程02020404050506062.4 设备管理2.5 总结2.6 习题2 CUDA2 CUDA编程模型编程模型2.1 CUDA编程模型概述2.1.1 CUDA编程结构01012.1.2 内存管理02022.1.3 线程管理03032.1.4 启动一个CUDA核函数04042.1.5 编写核函数05052.1.6 验证核函数06062 CUDA2 CUDA编程模型编程模型2.1 CUDA编
3、程模型概述2.1.7 处理错误1 12.1.8 编译和执行2 22 CUDA2 CUDA编程模型编程模型2.2 给核函数计时A2.2.1 用CPU计时器计时2.2.2 用nvprof工具计时B2 CUDA2 CUDA编程模型编程模型2.3 组织并行线程2.3.1 使用块和线程建立矩阵索引2.3.2 使用二维网格和二维块对矩阵求和2.3.3 使用一维网格和一维块对矩阵求和2.3.4 使用二维网格和一维块对矩阵求和2.4 设备管理2 CUDA2 CUDA编程模型编程模型2.4.1 使用运行时API查询GPU信息2.4.2 确定最优GPU2.4.3 使用nvidia-smi查询GPU信息2.4.4
4、在运行时设置设备DCAB043 CUDA执行模型3 CUDA3 CUDA执行模型执行模型3.1 CUDA执行模型概述3.2 理解线程束执行的本质3.3 并行性的表现3.6 动态并行3.5 展开循环3.4 避免分支分化3 CUDA3 CUDA执行模型执行模型3.7 3.7 总总结结3.8 3.8 习习题题3.1 CUDA执行模型概述3 CUDA3 CUDA执行模型执行模型3.1.1 GPU架构概述3.1.2 Fermi架构3.1.3 Kepler架构3.1.4 配置文件驱动优化3.2 理解线程束执行的本质3 CUDA3 CUDA执行模型执行模型3.2.1 线程束和线程块3.2.2 线程束分化3.
5、2.3 资源分配3.2.6 同步3.2.5 占用率3.2.4 延迟隐藏3 CUDA3 CUDA执行模型执行模型3.2 理解线程束执行的本质3.2.7 可扩展性3 CUDA3 CUDA执行模型执行模型3.3 并行性的表现3.3.1 用nvprof检测活跃的线程束01013.3.2 用nvprof检测内存操作02023.3.3 增大并行性03033 CUDA3 CUDA执行模型执行模型3.4 避免分支分化3.4.1 并行归约问题3.4.2 并行归约中的分化3.4.3 改善并行归约的分化3.4.4 交错配对的归约3 CUDA3 CUDA执行模型执行模型3.5 展开循环01013.5.1 展开的归约0
6、2023.5.2 展开线程的归约0 03 33.5.3 完全展开的归约0 04 43.5.4 模板函数的归约3 CUDA3 CUDA执行模型执行模型3.6 动态并行3.6.1 嵌套执行3.6.2 在GPU上嵌套Hello World3.6.3 嵌套归约054 全局内存4 4 全局内存全局内存01014.1 CUDA内存模型概述02024.2 内存管理0 03 34.3 内存访问模式0 04 44.4 核函数可达到的带宽0 05 54.5 使用统一内存的矩阵加法0 06 64.6 总结4 4 全局内存全局内存4.7 习题4 4 全局内存全局内存4.1 CUDA内存模型概述4.1.2 CUDA内存
7、模型4.1.1 内存层次结构的优点4.2 内存管理4 4 全局内存全局内存4.2.1 内存分配和释放4.2.2 内存传输4.2.3 固定内存4.2.6 统一内存寻址4.2.5 统一虚拟寻址4.2.4 零拷贝内存4 4 全局内存全局内存4.3 内存访问模式4.3.1 对齐与合并访问01014.3.2 全局内存读取02024.3.3 全局内存写入03034.3.4 结构体数组与数组结构体04044.3.5 性能调整05054 4 全局内存全局内存4.4 核函数可达到的带宽4.4.1 内存带宽4.4.2 矩阵转置问题065 共享内存和常量内存5 5 共享内存和常量内存共享内存和常量内存5.1 CUD
8、A共享内存概述5.2 共享内存的数据布局5.3 减少全局内存访问5.6 线程束洗牌指令5.5 常量内存5.4 合并的全局内存访问5 5 共享内存和常量内存共享内存和常量内存AB5.7 5.7 总结总结5.8 5.8 习题习题5 5 共享内存和常量内存共享内存和常量内存5.1 CUDA共享内存概述5.1.1 共享内存01015.1.2 共享内存分配02025.1.3 共享内存存储体和访问模式03035.1.4 配置共享内存量04045.1.5 同步05055 5 共享内存和常量内存共享内存和常量内存5.2 共享内存的数据布局A5.2.1 方形共享内存5.2.2 矩形共享内存B5 5 共享内存和常
9、量内存共享内存和常量内存5.3 减少全局内存访问5.3.1 使用共享内存的并行归约5.3.2 使用展开的并行归约5.3.3 使用动态共享内存的并行归约5.3.4 有效带宽5.4 合并的全局内存访问5 5 共享内存和常量内存共享内存和常量内存5.4.2 使用共享内存的矩阵转置5.4.4 使用展开的矩阵转置5.4.1 基准转置内核5.4.3 使用填充共享内存的矩阵转置5.4.5 增大并行性5 5 共享内存和常量共享内存和常量内存内存5.5 常量内存AB5.5.2 与只读缓存的比较5.5.1 使用常量内存实现一维模板5.6 线程束洗牌指令5 5 共享内存和常量内存共享内存和常量内存5.6.2 线程束
10、内的共享数据5.6.1 线程束洗牌指令的不同形式5.6.3 使用线程束洗牌指令的并行归约076 流和并发6 6 流和并发流和并发01016.1 流和事件概述02026.2 并发内核执行0 03 36.3 重叠内核执行和数据传输0 04 46.4 重叠GPU和CPU执行0 05 56.5 流回调0 06 66.6 总结6 6 流和并发流和并发6.7 习题6 6 流和并发流和并发6.1 流和事件概述6.1.1 CUDA6.1.1 CUDA流流6.1.2 6.1.2 流调流调度度6.1.5 6.1.5 流同流同步步6.1.4 CUDA6.1.4 CUDA事件事件6.1.3 6.1.3 流的流的优先级
11、优先级6.2 并发内核执行6 6 流和并发流和并发6.2.2 Fermi GPU上的虚假依赖关系6.2.4 用环境变量调整流行为6.2.6 默认流的阻塞行为6.2.1 非空流中的并发内核6.2.3 使用OpenMP的调度操作6.2.5 GPU资源的并发限制6 6 流和并发流和并发6.2 并发内核执行6.2.7 创建流间依赖关系6 6 流和并发流和并发6.3 重叠内核执行和数据传输6.3.1 使用深度优先调度重叠6.3.2 使用广度优先调度重叠087 调整指令级原语7 7 调整指令级原语调整指令级原语01017.1 CUDA指令概述7.2 程序优化指令02027.3 总结03037.4 习题04
12、047 7 调整指令级原语调整指令级原语7.1 CUDA指令概述CBA7.1.1 浮点指令7.1.2 内部函数和标准函数7.1.3 原子操作指令7 7 调整指令级原语调整指令级原语7.2 程序优化指令7.2.1 单精度与双精度的比较7.2.2 标准函数与内部函数的比较7.2.3 了解原子指令7.2.4 综合范例098 GPU加速库和OpenACC8 GPU8 GPU加速库和加速库和OpenACCOpenACC8.2 cuSPARSE库8.4 cuFFT库8.6 CUDA 6.0中函数库的介绍8.1 CUDA库概述8.3 cuBLAS库8.5 cuRAND库8 GPU8 GPU加速库和加速库和O
13、penACCOpenACC8.7 CUDA函数库的性能研究8.8 OpenACC的使用8.9 总结8.10 习题DCABLOGOLOGOhttps:/8 GPU8 GPU加加速库和速库和OpenACCOpenACC8.1 CUDA库概述A8.1.1 CUDA库支持的作用域8.1.2 通用的CUDA库工作流B8 GPU8 GPU加速库和加速库和OpenACCOpenACC8.2 cuSPARSE库01018.2.1 cuSPARSE数据存储格式02028.2.2 用cuSPARSE进行格式转换03038.2.3 cuSPARSE功能示例04048.2.4 cuSPARSE发展中的重要主题0505
14、8.2.5 cuSPARSE小结8.3 cuBLAS库8 GPU8 GPU加速库和加速库和OpenACCOpenACC8.3.1 管理cuBLAS数据8.3.2 cuBLAS功能示例8.3.3 cuBLAS发展中的重要主题8.3.4 cuBLAS小结8 GPU8 GPU加速库和加速库和OpenACCOpenACC8.4 cuFFT库8.4.2 cuFFT功能示例1 13 32 28.4.1 使用cuFFT API8.4.3 cuFFT小结8.5 cuRAND库8 GPU8 GPU加速库和加速库和OpenACCOpenACC8.5.1 拟随机数或伪随机数的选择8.5.2 cuRAND库概述8.5
15、.3 cuRAND介绍8.5.4 cuRAND发展中的重要主题DCAB8 GPU8 GPU加速库和加速库和OpenACCOpenACC8.6 CUDA 6.0中函数库的介绍8.6.1 Drop-In库8.6.2 多GPU库8.7 CUDA函数库的性能研究8 GPU8 GPU加速库和加速库和OpenACCOpenACC8.7.2 cuBLAS与MKL BLAS的比较8.7.4 CUDA库性能小结8.7.1 cuSPARSE与MKL的比较8.7.3 cuFFT与FFTW及MKL的比较8 GPU8 GPU加速库和加速库和OpenACCOpenACC8.8 OpenACC的使用8.8.1 OpenAC
16、C计算指令的使用01018.8.2 OpenACC数据指令的使用02028.8.3 OpenACC运行时API03038.8.4 OpenACC和CUDA库的结合04048.8.5 OpenACC小结0505109 多GPU编程9 9 多多GPUGPU编程编程9.2 多GPU间细分计算9.4 多GPU上的有限差分9.6 总结9.1 从一个GPU到多GPU9.3 多GPU上的点对点通信9.5 跨GPU集群扩展应用程序9 9 多多GPUGPU编程编程9.7 习题9 9 多多GPUGPU编程编程9.1 从一个GPU到多GPUCBA9.1.1 在多GPU上执行9.1.2 点对点通信9.1.3 多GPU
17、间的同步9 9 多多GPUGPU编程编程9.2 多GPU间细分计算9.2.2 单主机线程分配工作1 13 32 29.2.1 在多设备上分配内存9.2.3 编译和执行9.3 多GPU上的点对点通信9 9 多多GPUGPU编程编程9.3.2 点对点的内存复制9.3.1 实现点对点访问9.3.3 统一虚拟寻址的点对点内存访问9 9 多多GPUGPU编程编程9.4 多GPU上的有限差分9.4.1 二维波动方程的模板计算01019.4.2 多GPU程序的典型模式02029.4.3 多GPU上的二维模板计算03039.4.4 重叠计算与通信04049.4.5 编译和执行05059 9 多多GPUGPU编
18、程编程9.5 跨GPU集群扩展应用程序01019.5.1 CPU到CPU的数据传输02029.5.2 使用传统MPI在GPU和GPU间传输数据03039.5.3 使用CUDA-aware MPI进行GPU到GPU的数据传输04049.5.4 使用CUDA-aware MPI进行节点内GPU到GPU的数据传输05059.5.5 调整消息块大小06069.5.6 使用GPUDirect RDMA技术进行GPU到GPU的数据传输1110 程序实现的注意事项10 10 程序实现的注意事项程序实现的注意事项10.2 配置文件驱动优化10.4 将C程序移植到CUDA C的案例研究10.6 习题10.1 C
19、UDA C的开发过程10.3 CUDA调试10.5 总结LOGOLOGOhttps:/10 10 程序程序实现的注实现的注意事项意事项10.1 CUDA C的开发过程010110.1.1 APOD开发周期020210.1.2 优化因素0 03 310.1.3 CUDA代码编译0 04 410.1.4 CUDA错误处理10 10 程序实现的注意事项程序实现的注意事项10.2 配置文件驱动优化CBA10.2.1 使用nvprof寻找优化因素10.2.2 使用nvvp指导优化10.2.3 NVIDIA工具扩展10 10 程序实现的注意程序实现的注意事项事项10.3 CUDA调试10.3.1 10.3.1 内内核调试核调试10.3.2 10.3.2 内内存调试存调试10.3.3 10.3.3 调调试小结试小结10 10 程序实现的注意程序实现的注意事项事项10.4 将C程序移植到CUDA C的案例研究10.4.1 评估crypt010110.4.2 并行crypt020210.4.4 部署crypt040410.4.3 优化crypt030310.4.5 移植crypt小结050512附录 推荐阅读附录 推荐阅读感谢聆听