CUDA C++编程指南(1)——简介
AI-安全-功耗 CUBE 博客目录导读
目录
1. 简介
1.1. 使用GPU的优势
1.2. CUDA®:通用并行计算平台与编程模型
1.3. 可扩展的编程模型
1.4. 博客结构
1. 简介
1.1. 使用GPU的优势
图形处理单元(GPU)在相近的价格和功耗范围内,能提供比CPU高得多的指令吞吐量和内存带宽。许多应用程序利用这些更高性能在GPU上运行得比CPU更快(参见GPU Applications)。其他计算设备如FPGA虽然也非常节能,但编程灵活性远不如GPU。
【注意】:
图形限定词源于GPU最初创建时的背景。二十年前,GPU被设计为专门用于加速图形渲染的处理器。在实时、高清、3D图形市场需求的持续推动下,它已发展成为一种通用处理器,可用于远不止图形渲染的更多工作负载。
GPU和CPU之间的能力差异源于它们设计目标的根本不同。CPU的设计目标是尽可能快地执行一系列称为线程的操作,并能并行执行几十个这样的线程;而GPU的设计初衷则是擅长并行执行数千个线程(通过牺牲单线程性能来换取更高的整体吞吐量)。
GPU专为高度并行计算而设计,因此其架构将更多晶体管用于数据处理而非数据缓存和流控制。下图展示了CPU与GPU芯片资源分配的典型对比示意图。
图1 GPU将更多晶体管用于数据处理
将更多晶体管用于数据处理(例如浮点计算)有利于高度并行计算;GPU可以通过计算来隐藏内存访问延迟,而不是依赖大型数据缓存和复杂的流控制来避免长内存访问延迟,这两者在晶体管成本方面都非常昂贵。
通常来说,应用程序会同时包含并行部分和串行部分,因此系统会采用GPU和CPU混合的设计方案,以实现整体性能最大化。具有高度并行性的应用程序可以利用GPU的大规模并行特性,从而获得比CPU更高的性能。
1.2. CUDA®:通用并行计算平台与编程模型
2006年11月,NVIDIA®推出了CUDA®,这是一个通用并行计算平台和编程模型,它利用NVIDIA GPU中的并行计算引擎,以比CPU更高效的方式解决许多复杂的计算问题。
CUDA附带了一个软件开发环境,允许开发者使用C++作为高级编程语言。如下图所示,它还支持其他语言、应用程序接口或基于指令的方法,例如FORTRAN、DirectCompute和OpenACC。
图2 GPU计算应用。CUDA旨在支持多种语言和应用程序编程接口。
1.3. 可扩展的编程模型
多核CPU和众核GPU的出现意味着主流处理器芯片现在已成为并行系统。面临的挑战是开发能够透明扩展并行性以利用日益增多的处理器核心的应用软件,就像3D图形应用能透明地将其并行性扩展到具有不同核心数量的众核GPU上一样。
CUDA并行编程模型旨在克服这一挑战,同时为熟悉C等标准编程语言的程序员保持较低的学习曲线。
其核心是三个关键抽象概念——线程组层次结构、共享内存和屏障同步——这些概念通过最少的语言扩展直接向程序员开放。
这些抽象提供了细粒度的数据并行和线程并行,嵌套在粗粒度的数据并行和任务并行之中。它们指导程序员将问题划分为可以由线程块并行独立解决的粗粒度子问题,并将每个子问题进一步划分为可以由块内所有线程协作并行解决的更细粒度部分。
这种分解方式通过让线程在解决每个子问题时相互协作,既保留了语言表达能力,又实现了自动可扩展性。实际上,每个线程块都可以按任意顺序、并发或顺序地在GPU上的任意可用多处理器上进行调度,因此如下图所示,编译后的CUDA程序可以在任意数量的多处理器上执行,且只有运行时系统需要知道实际的多处理器数量。
这种可扩展的编程模型使得GPU架构能够通过简单地增加多处理器数量和内存分区来覆盖广泛的市场范围:从高性能发烧友级GeForce GPU和专业级Quadro与Tesla计算产品,到各种价格亲民的主流GeForce GPU(所有支持CUDA的GPU列表请参见CUDA-Enabled GPUs)。
图3 自动扩展
【注意】:
GPU的核心架构由一系列流式多处理器(SM)阵列构成(详见Hardware Implementation)。多线程程序会被划分为多个线程块,这些线程块彼此独立执行。因此,拥有更多多处理器的GPU能够以更短时间自动完成程序执行,相比多处理器较少的GPU具有明显优势。
1.4. 文档结构
本博客分为以下部分:
-
简介 是对CUDA的总体介绍。
-
编程模型 概述了CUDA编程模型。
-
编程接口 描述了各编程接口。
-
硬件实现 描述了硬件实现方案。
-
性能指南 提供了一些关于如何实现最佳性能的指导。
-
支持CUDA的GPU 列出了所有支持CUDA的设备。
-
C++语言扩展 是对C++语言所有扩展的详细描述。
-
协作组 描述了针对不同CUDA线程组的同步原语。
-
CUDA动态并行 描述了如何从一个内核启动和同步另一个内核。
-
虚拟内存管理 描述了如何管理统一虚拟地址空间。
-
流序内存分配器 描述了应用程序如何对内存分配和释放进行排序。
-
图内存节点 描述了图如何创建并拥有内存分配。
-
数学函数 列出了CUDA支持的数学函数。
-
C++语言支持 列出了设备代码中支持的C++特性。
-
纹理获取 提供了关于纹理获取的更多细节。
-
计算能力 提供了各种设备的技术规格以及更多架构细节。
-
Driver API 介绍了底层驱动API。
-
CUDA环境变量 列出了所有CUDA环境变量。
-
统一内存编程 介绍了统一内存编程模型。
