第一章 CUDA介绍
1.1 使用GPUs的好处
在相同的价格和功耗范围内,图形处理器 GPU 比 CPU 提供了更高的指令吞吐量和内存带宽, 许多应用程序利用这些更高的功能在 GPU 上比在 CPU 上运行得更快。相比较其他计算设备,如 FPGA,也是非常节能的,但其提供了比 GPU 少得多的编程灵活性。
GPU 和 CPU 之间的这种性能差异之所以存在,是因为它们在设计时考虑到了不同的目标。CPU 被设计成能够尽可能快地执行一系列操作(称为线程) ,并且能够并行地执行几十个这样的线程。GPU 被设计成能够并行执行数以千计的线程(缓冲较慢的单线程性能以获得更大的吞吐量)。
GPU专门用于高度并行的计算,因此设计成更多的晶体管用于数据处理而不是数据缓存和流量控制。示意图1显示了 CPU 芯片资源与 GPU 芯片资源的示例分布。
将更多的晶体管用于数据处理,例如浮点运算,有利于高度并行的计算;GPU 可以通过计算隐藏存储器访问延迟,而不需要依赖大型数据缓存和复杂的流控制来避免长的存储器访问延迟,因为这两者在晶体管方面都很昂贵。
一般来说,应用程序具有并行部分和顺序部分的混合,因此系统设计采用 GPU 和 CPU 的混合,以最大限度地提高整体性能。具有高度并行性的应用程序可以利用图形处理器的这种大规模并行处理机特性来获得比 CPU 更高的性能。
1.2 CUDA: 一个通用的并行计算平台和编程模型
2006年11月,NVIDIA 推出了 CUDA,这是一个通用的并行计算平台和编程模型,利用 NVIDIA 图形处理器中的并行计算引擎,以比 CPU 更有效的方式解决许多复杂的计算问题。
CUDA 提供了一个软件环境,允许开发人员使用 C + + 作为高级语言。同时也支持其他语言、应用程序编程接口或基于指令的方法,如 FORTRAN、 DirectCompute、 OpenACC。
1.3可伸缩编程模型
多核 CPU 和多核 GPU 的出现意味着主流处理器芯片现在是并行系统。挑战在于开发能够透明地扩展其并行性的应用软件,以利用不断增长的处理器核心数量,就像3D图形应用程序能够透明地扩展其并行性以适应多个核心数量差异很大的GPU一样
CUDA 并行编程模型旨在克服这一挑战,同时为熟悉 C 等标准编程语言的程序员保持较低的学习曲线。
其核心是三个关键的抽象ーー线程组的层次结构、共享内存和障碍同步ーー这些抽象只是作为最小的语言扩展集向程序员公开。
这些抽象提供了细粒度的数据平行和线程并行性,嵌套在粗粒度的数据平行和任务并行中。它们指导程序员将问题划分为可以通过线程块独立并行解决的粗粒子问题,并将每个子问题划分为可以通过块内所有线程并行协作解决的更细粒子问题。
这种分解通过允许线程在解决每个子问题时进行协作来保持语言的表达能力,同时支持自动伸缩性。事实上,每个线程块都可以在 GPU 中任何一个可用的多处理器上以任意顺序进行调度,并发或顺序执行,这样一个编译后的 CUDA 程序就可以在任意数量的多处理器上执行,而且只有运行时系统需要知道物理多处理器的数量。
这种可伸缩的编程模型允许 GPU 架构通过简单地缩放多处理器和内存分区的数量来跨越广泛的市场范围:从高性能的 GeForce 图形处理器和专业的 Quadro 和 Tesla 计算产品到各种廉价的主流 GeForce 图形处理器
GPU 是围绕流式多处理器(SM)阵列构建的。一个多线程程序被划分成多个独立执行的线程块,因此,一个具有更多处理器的 GPU 执行该程序的时间少于一个具有更少处理器的 GPU
1.4 CUDA 开发文件架构
本说明文档分为以下几节: (以下章节陆续会在CUDA专栏更新)
- 介绍:对 CUDA 的一般介绍(本章)
- 编程模型:概述CUDA 编程模型
- 编程接口:描述了编程接口
- 硬件实现:描述了硬件实现
- 性能指南:如何实现最佳性能提供了一些指导
- 启用 CUDA 的 GPU: 列出了所有启用 CUDA 的设备
- C + + 语言扩展:对 C + + 语言的所有扩展的详细描述
- 协作组:描述了各组 CUDA 线程的同步原语
- CUDA 动态并行性:描述了如何从一个内核启动并同步另一个内核
- 虚拟内存管理:描述了如何管理统一的虚拟地址空间
- 流有序内存分配器:描述了应用程序如何进行内存分配和释放
- 图形内存节点:描述了图形如何创建和拥有内存分配
- 数学函数:列出了 CUDA 支持的数学函数
- C + + 语言支持:列出了设备代码中支持的 C + + 特性
- 纹理获取:提供了更多关于纹理获取的细节
- 计算能力:给出了各种设备的技术规范,以及更多的体系结构细节
- 驱动程序 API: 引入了底层驱动程序 API
- CUDA 环境变量:列出了所有的 CUDA 环境变量
- 统一内存编程:引入了统一内存编程模型
当 GPU 最初被创建的时候,二十年前,它被设计成一个专门的处理器来加速图形渲染。由于市场对实时、高清、3D 图形的需求无法满足,它已经发展成为一种通用处理器,用于更多的工作负载,而不仅仅是图形渲染。