作品简介

本书主要介绍了如何使用GPU和利用CUDAC语言对其进行编程的。首先从基本的CUDA概念及结构讲起,一步一步地引导读者进入CUDA的内部世界,由浅入深地介绍了其编程要求及其内部架构,使读者对其有了整体印象后,逐步深入了解其内部机能,后介绍了GPU的一些专用函数和注意事项。

程润伟(John Cheng),博士是休斯敦BGP靠前的研究科学家,利用GPU开发出了地震成像产品,并开发了许多异构计算平台上的高性能并行生产应用程序。

马克斯·格罗斯曼(Max Grossman)是GPU计算方面的专家,主要用CUDA解决医学影像、机器学习和地球物理学等问题。

泰·麦克切尔(Ty McKercher)是NVIDIA公司的首席方案架构师,他领导的团队专攻跨行业的视觉计算机系统架构。他通常负责在新兴技术评估期间促进客户和产品工程团队之间的沟通交流。

作品目录

  • 译者序
  • 推荐序
  • 自序
  • 作者简介
  • 技术审校者简介
  • 前言
  • 致谢
  • 第1章 基于CUDA的异构并行计算
  • 1.1 并行计算
  • 1.1.1 串行编程和并行编程
  • 1.1.2 并行性
  • 1.1.3 计算机架构
  • 1.2 异构计算
  • 1.2.1 异构架构
  • 1.2.2 异构计算范例
  • 1.2.3 CUDA:一种异构计算平台
  • 1.3 用GPU输出Hello World
  • 1.4 使用CUDA C编程难吗
  • 1.5 总结
  • 1.6 习题
  • 第2章 CUDA编程模型
  • 2.1 CUDA编程模型概述
  • 2.1.1 CUDA编程结构
  • 2.1.2 内存管理
  • 2.1.3 线程管理
  • 2.1.4 启动一个CUDA核函数
  • 2.1.5 编写核函数
  • 2.1.6 验证核函数
  • 2.1.7 处理错误
  • 2.1.8 编译和执行
  • 2.2 给核函数计时
  • 2.2.1 用CPU计时器计时
  • 2.2.2 用nvprof工具计时
  • 2.3 组织并行线程
  • 2.3.1 使用块和线程建立矩阵索引
  • 2.3.2 使用二维网格和二维块对矩阵求和
  • 2.3.3 使用一维网格和一维块对矩阵求和
  • 2.3.4 使用二维网格和一维块对矩阵求和
  • 2.4 设备管理
  • 2.4.1 使用运行时API查询GPU信息
  • 2.4.2 确定最优GPU
  • 2.4.3 使用nvidia-smi查询GPU信息
  • 2.4.4 在运行时设置设备
  • 2.5 总结
  • 2.6 习题
  • 第3章 CUDA执行模型
  • 3.1 CUDA执行模型概述
  • 3.1.1 GPU架构概述
  • 3.1.2 Fermi架构
  • 3.1.3 Kepler架构
  • 3.1.4 配置文件驱动优化
  • 3.2 理解线程束执行的本质
  • 3.2.1 线程束和线程块
  • 3.2.2 线程束分化
  • 3.2.3 资源分配
  • 3.2.4 延迟隐藏
  • 3.2.5 占用率
  • 3.2.6 同步
  • 3.2.7 可扩展性
  • 3.3 并行性的表现
  • 3.3.1 用nvprof检测活跃的线程束
  • 3.3.2 用nvprof检测内存操作
  • 3.3.3 增大并行性
  • 3.4 避免分支分化
  • 3.4.1 并行归约问题
  • 3.4.2 并行归约中的分化
  • 3.4.3 改善并行归约的分化
  • 3.4.4 交错配对的归约
  • 3.5 展开循环
  • 3.5.1 展开的归约
  • 3.5.2 展开线程的归约
  • 3.5.3 完全展开的归约
  • 3.5.4 模板函数的归约
  • 3.6 动态并行
  • 3.6.1 嵌套执行
  • 3.6.2 在GPU上嵌套Hello World
  • 3.6.3 嵌套归约
  • 3.7 总结
  • 3.8 习题
  • 第4章 全局内存
  • 4.1 CUDA内存模型概述
  • 4.1.1 内存层次结构的优点
  • 4.1.2 CUDA内存模型
  • 4.2 内存管理
  • 4.2.1 内存分配和释放
  • 4.2.2 内存传输
  • 4.2.3 固定内存
  • 4.2.4 零拷贝内存
  • 4.2.5 统一虚拟寻址
  • 4.2.6 统一内存寻址
  • 4.3 内存访问模式
  • 4.3.1 对齐与合并访问
  • 4.3.2 全局内存读取
  • 4.3.3 全局内存写入
  • 4.3.4 结构体数组与数组结构体
  • 4.3.5 性能调整
  • 4.4 核函数可达到的带宽
  • 4.4.1 内存带宽
  • 4.4.2 矩阵转置问题
  • 4.5 使用统一内存的矩阵加法
  • 4.6 总结
  • 4.7 习题
  • 第5章 共享内存和常量内存
  • 5.1 CUDA共享内存概述
  • 5.1.1 共享内存
  • 5.1.2 共享内存分配
  • 5.1.3 共享内存存储体和访问模式
  • 5.1.4 配置共享内存量
  • 5.1.5 同步
  • 5.2 共享内存的数据布局
  • 5.2.1 方形共享内存
  • 5.2.2 矩形共享内存
  • 5.3 减少全局内存访问
  • 5.3.1 使用共享内存的并行归约
  • 5.3.2 使用展开的并行归约
  • 5.3.3 使用动态共享内存的并行归约
  • 5.3.4 有效带宽
  • 5.4 合并的全局内存访问
  • 5.4.1 基准转置内核
  • 5.4.2 使用共享内存的矩阵转置
  • 5.4.3 使用填充共享内存的矩阵转置
  • 5.4.4 使用展开的矩阵转置
  • 5.4.5 增大并行性
  • 5.5 常量内存
  • 5.5.1 使用常量内存实现一维模板
  • 5.5.2 与只读缓存的比较
  • 5.6 线程束洗牌指令
  • 5.6.1 线程束洗牌指令的不同形式
  • 5.6.2 线程束内的共享数据
  • 5.6.3 使用线程束洗牌指令的并行归约
  • 5.7 总结
  • 5.8 习题
  • 第6章 流和并发
  • 6.1 流和事件概述
  • 6.1.1 CUDA流
  • 6.1.2 流调度
  • 6.1.3 流的优先级
  • 6.1.4 CUDA事件
  • 6.1.5 流同步
  • 6.2 并发内核执行
  • 6.2.1 非空流中的并发内核
  • 6.2.2 Fermi GPU上的虚假依赖关系
  • 6.2.3 使用OpenMP的调度操作
  • 6.2.4 用环境变量调整流行为
  • 6.2.5 GPU资源的并发限制
  • 6.2.6 默认流的阻塞行为
  • 6.2.7 创建流间依赖关系
  • 6.3 重叠内核执行和数据传输
  • 6.3.1 使用深度优先调度重叠
  • 6.3.2 使用广度优先调度重叠
  • 6.4 重叠GPU和CPU执行
  • 6.5 流回调
  • 6.6 总结
  • 6.7 习题
  • 第7章 调整指令级原语
  • 7.1 CUDA指令概述
  • 7.1.1 浮点指令
  • 7.1.2 内部函数和标准函数
  • 7.1.3 原子操作指令
  • 7.2 程序优化指令
  • 7.2.1 单精度与双精度的比较
  • 7.2.2 标准函数与内部函数的比较
  • 7.2.3 了解原子指令
  • 7.2.4 综合范例
  • 7.3 总结
  • 7.4 习题
  • 第8章 GPU加速库和OpenACC
  • 8.1 CUDA库概述
  • 8.1.1 CUDA库支持的作用域
  • 8.1.2 通用的CUDA库工作流
  • 8.2 cuSPARSE库
  • 8.2.1 cuSPARSE数据存储格式
  • 8.2.2 用cuSPARSE进行格式转换
  • 8.2.3 cuSPARSE功能示例
  • 8.2.4 cuSPARSE发展中的重要主题
  • 8.2.5 cuSPARSE小结
  • 8.3 cuBLAS库
  • 8.3.1 管理cuBLAS数据
  • 8.3.2 cuBLAS功能示例
  • 8.3.3 cuBLAS发展中的重要主题
  • 8.3.4 cuBLAS小结
  • 8.4 cuFFT库
  • 8.4.1 使用cuFFT API
  • 8.4.2 cuFFT功能示例
  • 8.4.3 cuFFT小结
  • 8.5 cuRAND库
  • 8.5.1 拟随机数或伪随机数的选择
  • 8.5.2 cuRAND库概述
  • 8.5.3 cuRAND介绍
  • 8.5.4 cuRAND发展中的重要主题
  • 8.6 CUDA 6.0中函数库的介绍
  • 8.6.1 Drop-In库
  • 8.6.2 多GPU库
  • 8.7 CUDA函数库的性能研究
  • 8.7.1 cuSPARSE与MKL的比较
  • 8.7.2 cuBLAS与MKL BLAS的比较
  • 8.7.3 cuFFT与FFTW及MKL的比较
  • 8.7.4 CUDA库性能小结
  • 8.8 OpenACC的使用
  • 8.8.1 OpenACC计算指令的使用
  • 8.8.2 OpenACC数据指令的使用
  • 8.8.3 OpenACC运行时API
  • 8.8.4 OpenACC和CUDA库的结合
  • 8.8.5 OpenACC小结
  • 8.9 总结
  • 8.10 习题
  • 第9章 多GPU编程
  • 9.1 从一个GPU到多GPU
  • 9.1.1 在多GPU上执行
  • 9.1.2 点对点通信
  • 9.1.3 多GPU间的同步
  • 9.2 多GPU间细分计算
  • 9.2.1 在多设备上分配内存
  • 9.2.2 单主机线程分配工作
  • 9.2.3 编译和执行
  • 9.3 多GPU上的点对点通信
  • 9.3.1 实现点对点访问
  • 9.3.2 点对点的内存复制
  • 9.3.3 统一虚拟寻址的点对点内存访问
  • 9.4 多GPU上的有限差分
  • 9.4.1 二维波动方程的模板计算
  • 9.4.2 多GPU程序的典型模式
  • 9.4.3 多GPU上的二维模板计算
  • 9.4.4 重叠计算与通信
  • 9.4.5 编译和执行
  • 9.5 跨GPU集群扩展应用程序
  • 9.5.1 CPU到CPU的数据传输
  • 9.5.2 使用传统MPI在GPU和GPU间传输数据
  • 9.5.3 使用CUDA-aware MPI进行GPU到GPU的数据传输
  • 9.5.4 使用CUDA-aware MPI进行节点内GPU到GPU的数据传输
  • 9.5.5 调整消息块大小
  • 9.5.6 使用GPUDirect RDMA技术进行GPU到GPU的数据传输
  • 9.6 总结
  • 9.7 习题
  • 第10章 程序实现的注意事项
  • 10.1 CUDA C的开发过程
  • 10.1.1 APOD开发周期
  • 10.1.2 优化因素
  • 10.1.3 CUDA代码编译
  • 10.1.4 CUDA错误处理
  • 10.2 配置文件驱动优化
  • 10.2.1 使用nvprof寻找优化因素
  • 10.2.2 使用nvvp指导优化
  • 10.2.3 NVIDIA工具扩展
  • 10.3 CUDA调试
  • 10.3.1 内核调试
  • 10.3.2 内存调试
  • 10.3.3 调试小结
  • 10.4 将C程序移植到CUDA C的案例研究
  • 10.4.1 评估crypt
  • 10.4.2 并行crypt
  • 10.4.3 优化crypt
  • 10.4.4 部署crypt
  • 10.4.5 移植crypt小结
  • 10.5 总结
  • 10.6 习题
  • 附录 推荐阅读
展开全部