SciTech-ICEE-BigdataAIML-GPU: NVIDIA GPU: 概述+架构及共性+运行机制
深入GPU硬件架构及运行机制
https://www.cnblogs.com/timlly/p/11471507.html

目录
一、导言
1.1 为何要了解GPU?
1.2 内容要点
1.3 带着问题阅读
二、GPU概述
2.1 GPU是什么?
2.2 GPU历史
2.2.1 NV GPU发展史
2.2.2 NV GPU架构发展史
2.3 GPU的功能
三、GPU物理架构
3.1 GPU宏观物理结构
3.2 GPU微观物理结构
3.2.1 NVidia Tesla架构
3.2.2 NVidia Fermi架构
3.2.3 NVidia Maxwell架构
3.2.4 NVidia Kepler架构
3.2.5 NVidia Turing架构
3.3 GPU架构的共性
四、GPU运行机制
4.1 GPU渲染总览
4.2 GPU逻辑管线
4.3 GPU技术要点
4.3.1 SIMD和SIMT
4.3.2 co-issue
4.3.3 if - else语句
4.3.4 Early-Z
4.3.5 统一着色器架构(Unified shader Architecture)
4.3.6 像素块(Pixel Quad)
4.4 GPU资源机制
4.4.1 内存架构
4.4.2 GPU Context和延迟
4.4.3 CPU-GPU异构系统
4.4.4 GPU资源管理模型
4.4.5 CPU-GPU数据流
4.4.6 显像机制
4.5 Shader运行机制
4.6 利用扩展例证
五、总结
5.1 CPU vs GPU
5.2 渲染优化建议
5.3 GPU的未来
5.4 结语
特别说明
参考文献
一、导言
对于大多数图形渲染开发者,GPU是既熟悉又陌生的部件,
熟悉的是每天都需要跟它打交道,
陌生的是GPU就如一个黑盒,不知道其内部硬件架构,其运行机制。
本文以NVIDIA作为主线,将试图全面且深入地剖析GPU的硬件架构及运行机制,
主要涉及PC桌面级的GPU,不会覆盖移动端、专业计算、图形工作站级别的GPU。
若要通读本文,要求读者有一定图形学的基础,了解GPU渲染管线,最好写过HLSL、GLSL等shader代码。
1.1 为何要了解GPU?
了解GPU硬件架构和理解运行机制,笔者认为好处多多,总结出来有:
理解GPU其物理结构和运行机制,GPU由黑盒变白盒。
更易找出渲染瓶颈,写出高效率shader代码。
紧跟时代潮流,了解最前沿渲染技术.
1.2 内容要点
本文的内容要点提炼如下:
- GPU简介、历史、特性。
- GPU硬件架构。
- GPU和CPU的协调调度机制。
- GPU缓存结构。
- GPU渲染管线。
- GPU运行机制。
- GPU优化技巧。
1.3 带着问题阅读
适当带着问题去阅读技术文章,通常能加深理解和记忆,阅读本文可带着以下问题:
- GPU是如何与CPU协调工作的?
- GPU也有缓存机制吗?有几层?它们的速度差异多少?
- GPU的渲染流程有哪些阶段?它们的功能分别是什么?
- Early-Z技术是什么?发生在哪个阶段?这个阶段还会发生什么?会产生什么问题?如何解决?
- SIMD和SIMT是什么?它们的好处是什么?co-issue呢?
- GPU是并行处理的么?若是,硬件层是如何设计和实现的?
- GPC、TPC、SM是什么?Warp又是什么?它们和Core、Thread之间的关系如何?
- 顶点着色器(VS)和像素着色器(PS)可以是同一处理单元吗?为什么?
- 像素着色器(PS)的最小处理单位是1像素吗?为什么?会带来什么影响?
- Shader中的if、for等语句会降低渲染效率吗?为什么?
- 如下图,渲染相同面积的图形,三角形数量少(左)的还是数量多(右)的效率更快?为什么?
- GPU Context是什么?有什么作用?
- 造成渲染瓶颈的问题很可能有哪些?该如何避免或优化它们?
如果阅读完本文,能够非常清晰地回答以上所有问题,那么,恭喜你掌握到本文的精髓了! - GPU Context是什么?有什么作用?
- 造成渲染瓶颈的问题很可能有哪些?该如何避免或优化它们?
如果阅读完本文,能够非常清晰地回答以上所有问题,那么,恭喜你掌握到本文的精髓了!
二、GPU概述
2.1 GPU是什么?
GPU全称是Graphics Processing Unit,图形处理单元。它的功能最初与名字一致,是专门用于绘制图像和处理图元数据的特定芯片,后来渐渐加入了其它很多功能。
NVIDIA GPU芯片实物图。
我们日常讨论GPU和显卡时,经常混为一谈,严格来说是有所区别的。
GPU是显卡(Video card、Display card、Graphics card)最核心的部件,
但GPU之外,显卡还有扇热器、通讯元件、与主板和显示器连接的各类插槽。
对于PC桌面,生产GPU的厂商主要有两家:
- NVIDIA:英伟达,是当今首屈一指的图形渲染技术的引领者和GPU生产商佼佼者。NVIDIA的产品俗称N卡,代表产品有GeForce系列、GTX系列、RTX系列等。
- AMD:既是CPU生产商,也是GPU生产商,它家的显卡俗称A卡。代表产品有Radeon系列。
当然,NVIDIA和AMD也都生产移动端、图形工作站类型的GPU。
此外,生产移动端显卡的厂商还有ARM、Imagination Technology、高通等公司。
2.2 GPU历史
GPU自从上世纪90年代出现雏形以来,经过20多年的发展,已经发展成不仅仅是渲染图形这么简单,还包含了数学计算、物理模拟、AI运算等功能。
2.2.1 NV GPU发展史
以下是GPU发展节点表:
GPU架构
GPU微观物理结构
GPU的微观结构因不同厂商、不同架构都会有所差异,
但核心部件、概念、以及运行机制大同小异。
下面将展示部分架构的GPU微观物理结构。
3.2.1 NVidia Tesla架构

Tesla微观架构总览图如上。下面将阐述它的特性和概念:
- 有7组TPC(Texture/Processor Cluster,纹理处理簇)
- 每个TPC有两组SM(Stream Multiprocessor,流多处理器)
- 每个SM包含:
- 6个SP(Streaming Processor,流处理器)
- 2个SFU(Special Function Unit,特殊函数单元)
- L1缓存、MT Issue(多线程指令获取)、C-Cache(常量缓存)、共享内存
- 除了TPC核心单元,还有与显存、CPU、系统内存交互的各种部件。
3.2.2 NVidia Fermi架构

Fermi架构如上图,它的特性如下:
- 拥有16个SM
- 每个SM:
- 2个Warp(线程束)
- 两组共32个Core
- 16组加载存储单元(LD/ST)
- 4个特殊函数单元(SFU)
- 每个Warp:
- 16个Core
- Warp Scheduler
- Dispatch Unit
- 每个Core:
- 1个FPU(浮点数单元)
- 1个ALU(逻辑运算单元)
3.3 GPU架构的共性
纵观上一节的所有GPU架构,可以发现它们虽然有所差异,但存在着很多相同的概念和部件:
GPU设计大量用到 多层级、Cluster化设计、组织管理大量同款组件,
GPU的任务是天然并行的,现代GPU的架构都是以高度并行能力而设计的。
- GPC:
GPU被划分成多个GPCs(Graphics Processing Cluster),
每个GPC拥有多个SM(SMX、SMM), 和一个光栅化引擎(Raster Engine),
它们其中有很多的连接,最显著的是Crossbar,它可以连接GPCs和其它功能性模块(例如ROP或其他子系统)。 - SM、SMX、SMM
每个SM包含许多的Core(核心,有Thread执行数学运算用)。
例如在Core上调用一个Thread处理 顶点或像素着色器。
shader(开发的程序)是在SM上完成的。
SM设计(内核数量,指令单位,调度程序......)还因时间的推移而发生变化。 - TPC
- Warp
一个warp是由 32个Thread组成,以并行管理调度,
Warp Scheduler管理Warp(线程束,32个Thread作为一个Warp),
Warp Scheduler驱动Cores和其它单元,并将要执行的指令移交给Dispatch Units。
Warp是典型的SIMT(单Instruction多Thread,SIMD单Instruction多Data的升级)的实现,
Warp管理的32个Thread执行的都是"同一指令序列/程序",
只是每个Thread执行同一指令序列/程序时接受的"数据/参数"不同,
Warp化的好处,是 warp只要 "一套逻辑"( 对"一组指令序列"只要"解码一次就可多次并行执行" ),
芯片可以做的更快更小,之所以可以这么做,是由于GPU需要处理的任务是天然并行的。 - Thread
Thread不能独立执行指令, 而是组成warp的单位,而这些warp之间才能独立的执行指令。 - SP
一个高层组件,由许多组件构成。 - Core
运算核心,也叫流处理器Stream Processor
Core和其它单元由Warp Scheduler驱动。 - ALU
- FPU:
FPU是高精度的Float Processing Unit, 和 SFU分工不同,协作。 - SFU(Special Function Units)
- ROP
- Load/Store Unit
LD/ST(load/store)模块来加载和存储数据 - L1 Cache
- L2 Cache
- Memory
- Register File
以上各个部件的用途将在下一章详细阐述。
GPU为什么会有这么多层级, 且有这么多看似的部件?
答案是GPU的任务是天然并行的,现代GPU的架构都是以高度并行能力而设计的。
四、GPU运行机制
4.1 GPU渲染总览
由上一章可得知,现代GPU有着形似的结构,有很多并行的同款部件,
在运行机制上,也有很多共同点。下面是Fermi架构的运行机制总览图:
| GPU ARCH. |
|---|
![]() |
| SM ORG. |
|---|
![]() |
从Fermi开始NVIDIA使用类似的原理架构:
- 使用一个Giga Thread Engine来管理所有正在进行的工作,
- GPU被划分成多个GPCs(Graphics Processing Cluster),
每个GPC拥有多个SM(SMX、SMM), 和一个光栅化引擎(Raster Engine),
它们其中有很多的连接,最显著的是Crossbar,它可以连接GPCs和其它功能性模块(例如ROP或其他子系统)。 - shader(GPU开发者的程序)是在SM上完成的。
每个SM包含许多的Core(核心, 为Thread执行数学运算用)。
例如,调用一个Thread处理 顶点或像素着色器。 - Core和其它单元由Warp Scheduler驱动,
Warp Scheduler管理一组32个线程作为Warp(线程束),
并将要执行的指令移交给Dispatch Units。
GPU设计时确定这些单元的配置(GPC数, 每个GPC的SM数, ......)。
例如,
GM204有4个GPC,每个GPC有4个SM,
Tegra X1有1个GPC,2个SM,它们均采用Maxwell设计。
SM设计(内核数量,指令单位,调度程序......)还因时间的推移而发生变化,
并帮助使芯片变得如此高效,可以从高端台式机扩展到笔记本电脑移动。
对于某些GPU(如Fermi部分型号)的单个SM,包含:
- 32个Core(运算核心,也叫流处理器Stream Processor)
- 16个LD/ST(Load/Store)模块来加载和存储数据
- 4个SFU(Special Function Units)执行特殊数学运算(sin、cos、log等)
- 128KB 的 Register File(寄存器)
- 64KB 的 L1 Cache
- Uniform Cache(全局内存缓存)
- 纹理读取单元
- Texture Cache(纹理缓存)
- PolyMorph Engine:
attribute Setup(多边形引擎负责属性装配)、
VertexFetch(顶点拉取)、
曲面细分、
栅格化(这个模块可以理解为专门处理顶点有关的东西)。 - 2个Warp Schedulers:
这个模块负责warp调度,
一个warp由32个Thread组成,
Warp Schedulers 的指令通过 Dispatch Units 送到 Core 执行。 - Instruction Cache(指令缓存)
- Interconnect Network(内部链接网络)
4.2 GPU逻辑管线
了解上一节的部件和概念之后,可以深入阐述GPU的渲染过程和步骤。
下面将以Fermi家族的SM为例,进行逻辑管线的详细说明。

- 程序调用GPU或显卡驱动:
程序通过Graphics API(DX、GL、WEBGL)发出drawcall指令,指令会被推送到驱动程序,
驱动会检查指令的合法性,然后会把指令放到GPU可以读取的Pushbuffer。 - 经过一段时间或者显式调用flush指令后,驱动程序把Pushbuffer的内容发送给GPU,
GPU通过Host Interface(主机接口)接受这些命令,并通过Front End(前端)处理这些命令。 - 在Primitive Distributor(元分配器)开始GPU工作分配,
处理 Indexbuffer的顶点产生三角形, 分成Batches Tasks(批量任务),然后发送给多个GPCs。
这一步的理解,就是提交上N个三角形,分配给这几个PGC同时处理。
![1000134539]()
- 在GPC上,每个SM的Poly Morph Engine
通过Triangle Indices(三角形索引) 取出Vertex data(三角形的数据),
即图上的Vertex Fetch模块。 - 在获取Vertex data(三角形的数据)后,SM以Warp为单元来调度Threads开始处理顶点数据。
Warp是典型的SIMT(单Instruction多Thread,SIMD单Instruction多Data的升级)的实现,
也就是32个Thread:
执行的都是"同一指令序列/程序",
只是每个Thread执行同一指令序列/程序时接受的"数据/参数"不同,
Warp化的好处,是 warp只要 "一套逻辑"对"指令序列进行一次解码和多次并行执行"就可以,
芯片可以做的更小更快,之所以可以这么做,是由于GPU需要处理的任务是天然并行的。 - SM的Warp Scheduler 会按照顺序分发指令给整个Warp,
单个warp的Thread会lock-step(锁步)执行各自的指令,
如果Thread碰到不激活执行的情况也会be masked out(被遮掩)。
be masked out的原因有很多,例如:
当前Branch是if(data){...}, 一些Threads的data的条件是false,而同Warp其它Threads的data不是。
或者Branch是for(n;n;n++){...}, 每Thread的数据n(循环次数, 不是常量)不同,或一些因break提前终止。
因此在shader的Branch会显著加时间,
在一个warp的Branch,除非32个Thread都走到if或者else里面,不然,就是所有的Branch都过了一遍,
Thread不能独立执行指令, 而是以warp为单位,而这些warp之间才能独立的执行指令。 - warp的指令可以被一次完成,也可能经过多次调度
例如通常SM的LD/ST(加载存取)单元数量显式少于基础数学操作单元。 - Warp Scheduler高效地调度并行的指令序列任务:
由于某些指令比其他指令需要更长的时间才能完成,特别是内存加载,如果当前Warp正在执行这类指令,
Warp Scheduler就可能分配到另一个没有内存等待的Warp。
这是GPU克服 "内存读取延迟" 的关键,只要切换 Active Warp就行,为了使这种切换非常快,
Warp Scheduler管理的所有Warps,都在GPU寄存器文件上有寄存器。
Shader需要的寄存器越多,给Warp的空间越少,可用的Active Warp就越少。
Warp Scheduler最高效地解决"GPU寄存器分配"的矛盾,避免和减少因"寄存器分配"而产生的等待。
![1000134531]()
- GP(Graphic Processing)过程:
一旦warp完成了vertex-shader的所有指令,
运算结果会送到Viewport Transform模块,裁剪三角形后准备栅格化,
GPU会使用L1和L2 Cache 进 行vertex-shader 和 pixel-shader 的数据通信。
接下来这些三角形将被分割,再分配给多个GPC。
![1000134532]()
- GPC的Raster Engines(光栅引擎)处理Tiles(多个屏幕的)
三角形的范围,决定它将被分配到哪个Raster engines(光栅引擎),
每个 Raster engines 覆盖了多个屏幕上的tile,
这等于把三角形的渲染,分配到多个tile上面。
在像素阶段,就把 "按三角形划分" 变成了 "按显示的像素划分"。
![1000134533]()
- SM上的Attribute Setup保证了从vertex-shader来的数据经过插值后的pixel-shade是可读的。
- GPC上的Raster engines(光栅引擎)在它接收到的三角形上工作.
来负责这些这些三角形的Pixel信息的生成(同时会处理裁剪Clipping、背面剔除和Early-Z剔除)。 - 32个Pixel Thread将分成一组, 即 "8个2x2的像素块"(在像素着色器上的最小工作单元),
在这个像素线程,如果没有被三角形覆盖就会被遮掩,
SM的Warp Scheduler会管理 "像素着色器"任务的调度。 - 接下来的阶段就和vertex-shader的逻辑步骤完全一致,只是变成了在像素着色器线程执行。
由于不耗费任何性能,就可以获取一个像素线程内的值,导致锁步执行非常便利,
所有的线程可以保证 "所有的指令可以在同一点"。
现在像素着色器已经完成了颜色的计算,但是还有深度值的计算。
![1000134534]()
- 最后一步还有深度值的计算:
在这个点上,我们必须考虑三角形的原始api顺序,
然后才将数据移交给ROP(Render Output Unit,渲染输入单元),
一个ROP有很多ROP单元, ROP单元处理 "深度测试和framebuffer的混合",
深度和颜色的设置必须是 "Atomic Op.(原子操作)",
才能确保两个不同的三角形在同一个像素点没有冲突和错误。
4.3 GPU技术要点
由于上一节主要阐述GPU内部的工作流程和机制,
为了精简性,省略了很多知识点和过程,本节将对它们做进一步补充说明。
4.3.1 SIMD和SIMT
SIMD(Single Instruction Multiple Data) 是单指令多数据,
在GPU的ALU单元内,一条指令可以处理多维向量(经常是4D)的数据。
比如,有以下shader指令:
float4 c = a + b; // a, b都是float4类型
对于没有SIMD的处理单元,需要4条指令将4个float数值相加,汇编伪代码如下:
ADD c.x, a.x, b.x
ADD c.y, a.y, b.y
ADD c.z, a.z, b.z
ADD c.w, a.w, b.w
但有了SIMD技术,只需一条指令即可处理完:
SIMD_ADD c, a, b

SIMT(Single Instruction Multiple Threads,单指令多线程)是SIMD的升级版,
可对GPU的单个SM的多个Core同时处理 "同一指令",并且"每个Core存取的数据可以是不同的"。
SIMT_ADD c, a, b
上述指令会同时送入在单个SM所编组的全部Core,同时执行运算,但a、b 、c的值可以不同:

4.3.2 co-issue
co-issue是为了解决SIMD运算单元无法充分利用的问题。
例如下图,由于float数量的不同,ALU利用率从100%依次下降为75%、50%、25%。

为了解决着色器在低维向量的利用率低的问题,可以通过合并1D与3D, 或2D与2D的指令。
例如下图,DP3指令用了3D数据,ADD指令只有1D数据,
co-issue会自动将它们合并,在同一个ALU只需一个指令周期即可执行完。

但对Vector ALU(向量运算单元),如果其一变量既是 操作数 又是 存储数 的情况,无法启用co-issue技术:

于是Scalar Instruction Shader(标量指令着色器)应运而生,
它可以有效地组合任何Vector,开启co-issue技术,充分发挥SIMD的优势。
4.3.3 if - else语句

如上图,SM有8个ALU(Core),由于SIMD的特性,每个ALU的数据不一致,导致
if-else语句在某些ALU上执行的是true分支(黄色),有些ALU执行的是false分支(灰蓝色),
导致很多ALU的执行周期被masked out,拉长了整个执行周期。
最坏情况,同一个SM只有1/8(8是同一个SM的线程数,不同架构的GPU有所不同)的利用率。
同样,for循环也会导致类似的情形,例如以下shader代码:
void func(int count, int breakNum)
{
for(int i=0; i<count; ++i)
{
if (i == breakNum)
break;
else
// do something
}
}
由于每个ALU的count不同,加上有break分支,导致最快执行完shader的ALU可能是最慢的N分之一的时间,
但由于SIMD的特性,最快的那个ALU还要等待最慢的ALU执行完毕,才能接下一组指令的活!
也就白白浪费了很多时间周期。
4.3.4 Early-Z
- 早期,GPU的渲染管线的深度测试, 是在像素着色器之后才执行(下图),
会造成很多本不可见的像素, 执行了影响性能的像素着色器计算。
![1000134545]()
- 后来,为了减少像素着色器的额外开销,将深度测试提至像素着色器之前(下图),这就是Early-Z技术的由来。
![1000134546]()
Early-Z技术可以将很多无效的像素提前剔除,避免它们进入耗时严重的像素着色器。
Early-Z剔除的最小单位不是1像素,而是pixel quad(像素块, 2x2个像素),
详见[4.3.6 ](#4.3.6 像素块(pixel quad)))。
但是,以下情况会导致Early-Z失效:
- 开启Alpha Test:由于Alpha Test需要在像素着色器后面的Alpha Test阶段比较,所以无法在像素着色器之前就决定该像素是否被剔除。
- 开启Tex Kill:即在shader代码中有像素摒弃指令(DX的discard,OpenGL的clip)。
- 关闭深度测试。Early-Z建立在深度测试开启的条件下,启用Early-Z技术必须先启用深度测试。
开启Multi-Sampling:会影响周边像素,使Early-Z阶段因无法得知周边像素是否被裁剪而无法提前剔除。 - 以及其它任何导致需要混合后面颜色的操作。
此外,Early-Z技术会导致一个问题:深度数据冲突(depth data hazard)。

例子要结合上图,假设
数值深度值5,已经过Early-Z,即将写入Frame Buffer,
而深度值10刚好处于Early-Z,读取并对比当前缓存的深度值15,
结果就是10通过了Early-Z测试,会覆盖掉比自己小的深度值5,
最终frame buffer的深度值是错误的结果。
避免深度数据冲突的方法之一是在写入深度值之前,再次与frame buffer的值进行对比:

4.3.5 Unified shader Architecture(统一着色器架构)
早期的GPU,VS(顶点着色器)和PS(像素着色器)的硬件结构是独立的,它们各有各的寄存器、运算单元等部件。
很多时候,会造成VS与PS之间任务的不平衡。对于顶点数量多的任务,像素着色器空闲状态多;对于像素多的任务,顶点着色器的空闲状态多(下图)。

于是,为了解决VS和PS之间的不平衡,引入了Unified shader Architecture。
用了此架构的GPU,VS和PS用的都是相同的Core。也就是,同一个Core既可以是VS又可以是PS。

这样就解决了不同类型着色器之间的不平衡问题,还可以减少GPU的硬件单元,压缩物理尺寸和耗电量。此外,VS、PS可还可以和其它着色器(几何、曲面、计算)统一为一体。

4.3.6 像素块(Pixel Quad)
上一节步骤13提到:
32个像素线程将被分成一组,或者说8个2x2的像素块,这是在PS(像素着色器)上面的最小工作单元,在这个像素线程内,如果没有被三角形覆盖就会被遮掩,SM的Warp Scheduler会管理 PS的任务。
也就是,在PS会将相邻的四个像素作为不可分隔的一组,送入同一SM内4个不同的Core。
为什么PS(像素着色器) 处理的最小单元是 2x2的像素块?
作者推测有以下原因:
- 简化和加速像素分派的工作。
- 精简SM的架构,减少硬件单元数量和尺寸。
- 降低功耗,提高效能比。
- 无效像素虽然不会被存储结果,但可辅助有效像素求导函数。详见4.6 利用扩展例证。
这种设计虽然有其优势,但同时,也会激化 Over Draw(过绘制)的情况,付出额外的性能。
比如下图,白色的三角形只用了3个像素(绿色),按我们普通的思维,只需要3个Core绘制3次就可以。

但是,由于上面的3个像素分别占据了不同的像素块(橙色分隔),
实际上需要占用12个Core绘制12次(下图)。

这就会额外消耗300%的硬件性能,导致了更加严重的过绘制情况。
更多详情可以观看UE(虚幻)官方的视频教学:实时渲染深入探究。
4.4 GPU资源机制
本节将阐述GPU的内存访问、资源管理等机制。
4.4.1 内存架构
部分架构的GPU与CPU类似,也有多级缓存结构:寄存器、L1缓存、L2缓存、GPU显存、系统显存。

它们的存取速度从寄存器到系统内存依次变慢:
| 存储类型 | 寄存器 | 共享内存 | L1缓存 | L2缓存 | 纹理、常量缓存 | 全局内存 |
|---|---|---|---|---|---|---|
| 访问周期 | 1 | 1~32 | 1~32 | 32~64 | 400~600 | 400~600 |
由此可见,shader直接访问寄存器、L1、L2缓存还是比较快的,
但访问纹理、常量缓存和全局内存非常慢,会造成很高的延迟。
上面的多级缓存结构可被称为“CPU-Style”,还存在GPU-Style的内存架构:

这种架构的特点是ALU多,GPU上下文(Context)多,吞吐量高,依赖高带宽与系统内存交换数据。
4.4.2 GPU Context和延迟
由于SIMT技术的引入,导致很多同一个SM内的很多Core并不是独立的,当它们当中有部分Core需要访问到纹理、常量缓存和全局内存时,就会导致非常大的卡顿(Stall)。
例如下图中,有4组上下文(Context),它们共用同一组运算单元ALU。
4.5 Shader运行机制
Shader代码也跟常用的C++等语言类似,
需要将 "面向人类的高级语言(GLSL、HLSL、CGSL)"通过 "GPU Compiler(编译器)",
转成 "面向机器的二进制指令",二进制指令还可转译成汇编代码,以便技术人员查阅和调试。

由高级语言编译成汇编指令的过程,通常是在离线阶段执行,以减轻运行时的成本。
在执行阶段,CPU端将shader二进制指令, 经由PCI-e推送到GPU端,
GPU在执行代码时,会用Context 将 指令 分成若干Channel 推送到 各个Core的存储空间。
对现代GPU而言,可编程的阶段越来越多,包含但不限于:
VS(Vertex Shader, 顶点着色器)、
GS(Geometry Shader, 几何着色器)、
FS(Fragment Shader, 像素/片元着色器)、
CS(Compute Shader, 计算着色器)、
TSC(Tessellation Control Shader, 曲面细分控制着色器)、
...

这些着色器形成Pipelines(流水线式的并行化的渲染管线)。
下面将配合具体的例子说明。
下段是计算漫反射的经典代码:
sampler mySamp;
Texture2D<float3> myTex;
float3 lightDir;
float4 diffuseShader(float3 norm, float2 uv)
{
float3 kd;
kd = myTex.Sample(mySamp, uv);
kd *= clamp( dot(lightDir, norm), 0.0, 1.0);
return float4(kd, 1.0);
}
经过编译后成为汇编代码:
<diffuseShader>:
sample r0, v4, t0, s0
mul r3, v0, cb0[0]
madd r3, v1, cb0[1], r3
madd r3, v2, cb0[2], r3
clmp r3, r3, l(0.0), l(1.0)
mul o0, r0, r3
mul o1, r1, r3
mul o2, r2, r3
mov o3, l(1.0)
在执行阶段,以上汇编代码会被GPU推送到Execution Context(执行上下文),
然后ALU会逐条Detch(获取)、Decode(解码)汇编指令,并执行它们。

以上示例图只是单个ALU的执行情况,实际上,GPU有几十甚至上百个执行单元在同时执行shader指令:

对于SIMT架构的GPU,汇编指令有所不同,变成了SIMT特定指令代码:
<VEC8_diffuseShader>:
VEC8_sample vec_r0, vec_v4, t0, vec_s0
VEC8_mul vec_r3, vec_v0, cb0[0]
VEC8_madd vec_r3, vec_v1, cb0[1], vec_r3
VEC8_madd vec_r3, vec_v2, cb0[2], vec_r3
VEC8_clmp vec_r3, vec_r3, l(0.0), l(1.0)
VEC8_mul vec_o0, vec_r0, vec_r3
VEC8_mul vec_o1, vec_r1, vec_r3
VEC8_mul vec_o2, vec_r2, vec_r3
VEC8_mov o3, l(1.0)
并且Context以Core为单位组成共享的结构,同一个Core的多个ALU共享一组Context:

如果有多个Core,就会有更多的ALU同时参与shader计算,每个Core执行的数据是不同的,可能是顶点、图元、像素等任何数据:

4.6 利用扩展例证
NV shader thread group提供了OpenGL的扩展,
可以查询GPU的Thread、Core、SM、Warp等硬件有关的属性。
如果要开启次此扩展,需要满足以下条件:
- OpenGL 4.3+;
- GLSL 4.3+;
- 支持OpenGL 4.3+的NV显卡;
并且此扩展只在NV部分5代着色器内起作用:
This extension interacts with NV_gpu_program5
This extension interacts with NV_compute_program5
This extension interacts with NV_tessellation_program5
下面是具体的字段和代表的意义:
// 开启扩展
#extension GL_NV_shader_thread_group : require (or enable)
WARP_SIZE_NV // 单个线程束的线程数量
WARPS_PER_SM_NV // 单个SM的线程束数量
SM_COUNT_NV // SM数量
uniform uint gl_WarpSizeNV; // 单个线程束的线程数量
uniform uint gl_WarpsPerSMNV; // 单个SM的线程束数量
uniform uint gl_SMCountNV; // SM数量
in uint gl_WarpIDNV; // 当前线程束id
in uint gl_SMIDNV; // 当前线程束所在的SM id,取值[0, gl_SMCountNV-1]
in uint gl_ThreadInWarpNV; // 当前线程id,取值[0, gl_WarpSizeNV-1]
in uint gl_ThreadEqMaskNV; // 是否等于当前线程id的位域掩码。
in uint gl_ThreadGeMaskNV; // 是否大于等于当前线程id的位域掩码。
in uint gl_ThreadGtMaskNV; // 是否大于当前线程id的位域掩码。
in uint gl_ThreadLeMaskNV; // 是否小于等于当前线程id的位域掩码。
in uint gl_ThreadLtMaskNV; // 是否小于当前线程id的位域掩码。
in bool gl_HelperThreadNV; // 当前线程是否协助型线程。
上述所说的协助型线程gl_HelperThreadNV是指
在处理2x2的像素块时,那些未被图元覆盖的像素着色器线程将被标记为gl_HelperThreadNV = true,
将忽略它们的结果,不会存储。
但可辅助一些计算,如导数dFdx和dFdy。为了防止理解有误,贴出原文:
The variable
gl_HelperThreadNVspecifies if the current thread is a helper thread. In implementations supporting this extension, fragment shader invocations may be arranged in SIMD thread groups of 2x2 fragments called "quad". When a fragment shader instruction is executed on a quad, it's possible that some fragments within the quad will execute the instruction even if they are not covered by the primitive. Those threads are called helper threads. Their outputs will be discarded and they will not execute global store functions, but the intermediate values they compute can still be used by thread group sharing functions or by fragment derivative functions like dFdx and dFdy.
利用以上字段,可以编写特殊shader代码转成颜色信息,以便可视化窥探GPU的工作机制和流程。

利用NV扩展字段,可视化了VS(顶点着色器)、PS(像素着色器)的SM、Warp id,
为我们查探GPU的工作机制和流程提供了途径。
下面正式进入验证阶段,将以Geforce RTX 2060作为验证对象,具体信息如下:
操作系统: Windows 10 Pro, 64-bit
DirectX 版本: 12.0
GPU 处理器: GeForce RTX 2060
驱动程序版本: 417.71
Driver Type: Standard
Direct3D API 版本: 12
Direct3D 功能级别:12_1
CUDA 核心: 1920
核心时钟: 1710 MHz
内存数据速率: 14.00 Gbps
内存接口: 192-位
内存带宽: 336.05 GB/秒
全部可用的图形内存:22494MB
专用视频内存: 6144 MB GDDR6
系统视频内存: 0MB
共享系统内存: 16350MB
视频 BIOS 版本: 90.06.3F.00.73
IRQ: Not used
总线: PCI Express x16 Gen3
首先在应用程序创建包含两个三角形的顶点数据:
// set up vertex data (and buffer(s)) and configure vertex attributes
const float HalfSize = 1.0f;
float vertices[] = {
-HalfSize, -HalfSize, 0.0f, // left bottom
HalfSize, -HalfSize, 0.0f, // right bottom
-HalfSize, HalfSize, 0.0f, // top left
-HalfSize, HalfSize, 0.0f, // top left
HalfSize, -HalfSize, 0.0f, // right bottom
HalfSize, HalfSize, 0.0f, // top right
};
渲染采用的顶点着色器非常简单:
#version 430 core
layout (location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos, 1.0f);
}
片元着色器也是寥寥数行:
#version 430 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
绘制出来的原始画面如下:
紧接着,修改片元着色器,加入扩展所需的代码,并修改颜色计算:
#version 430 core
#extension GL_NV_shader_thread_group : require
uniform uint gl_WarpSizeNV; // 单个线程束的线程数量
uniform uint gl_WarpsPerSMNV; // 单个SM的线程束数量
uniform uint gl_SMCountNV; // SM数量
in uint gl_WarpIDNV; // 当前线程束id
in uint gl_SMIDNV; // 当前线程所在的SM id,取值[0, gl_SMCountNV-1]
in uint gl_ThreadInWarpNV; // 当前线程id,取值[0, gl_WarpSizeNV-1]
out vec4 FragColor;
void main()
{
// SM id
float lightness = gl_SMIDNV / gl_SMCountNV;
FragColor = vec4(lightness);
}
由上面的代码渲染的画面如下:
从上面可分析出一些信息:
画面共有32个亮度色阶,也就是Geforce RTX 2060有32个SM。
单个SM每次渲染16x16为单位的像素块,也就是每个SM有256个Core。
SM之间不是顺序分配像素块,而是无序分配。
不同三角形的接缝处出现断层,说明同一个像素块如果分属不同的三角形,就会分配到不同的SM进行处理。由此推断,相同面积的区域,如果所属的三角形越多,就会导致分配给SM的次数越多,消耗的渲染性能也越多。
接着修改片元着色器的颜色计算代码以显示Warp id:
// warp id
float lightness = gl_WarpIDNV / gl_WarpsPerSMNV;
FragColor = vec4(lightness);
得到如下画面:
由此可得出一些信息或推论:
画面共有32个亮度色阶,也就是每个SM有32个Warp,每个Warp有8个Core。
每个色块像素是4x8,由于每个Warp有8个Core,由此推断每个Core单次要处理2x2的最小单元像素块。
也是无序分配像素块。
三角形接缝处出现断层,同SM的推断一致。
再修改片元着色器的颜色计算代码以显示线程id:
// thread id
float lightness = gl_ThreadInWarpNV / gl_WarpSizeNV;
FragColor = vec4(lightness);
得到如下画面:
......
5.4 结语
https://www.cnblogs.com/timlly/p/11471507.html
本文系统地讲解了GPU的历史、发展、工作流程,
以及部分过程的细化说明和用到的各种技术,
我们可以看到GPU架构的动机、机制、瓶颈,以及未来的发展。
希望看完本文,大家能很好地答出导言提出的问题:1.3 带着问题阅读。
如果不能全部答出,也没关系,看有关章节,总能找到答案。
如果想更深入地了解GPU的设计细节、实现细节,
可阅读GPU厂商定期发布的白皮书和各大高校、机构发布的论文。
推荐一个GPU解说视频:A trip through the Graphics Pipeline 2011: Index,
虽然是多年前的视频,但比较系统、全面地讲解了GPU的机制和技术。
特别说明
感谢所有参考文献的作者们!
https://www.cnblogs.com/timlly/p/11471507.html
参考文献
Real-Time Rendering Resources
Life of a triangle - NVIDIA's logical pipeline
NVIDIA Pascal Architecture Whitepaper
NVIDIA Turing Architecture Whitepaper
Pomegranate: A Fully Scalable Graphics Architecture
Performance Optimization Guidelines and the GPU Architecture behind them
A trip through the Graphics Pipeline 2011
Graphic Architecture introduction and analysis
Exploring the GPU Architecture
Introduction to GPU Architecture
An Introduction to Modern GPU Architecture
GPU TECHNOLOGY: PAST, PRESENT, FUTURE
GPU Computing & Architectures
NVIDIA VOLTA
NVIDIA TURING
Graphics processing unit
GPU并行架构及渲染优化
渲染优化-从GPU的结构谈起
GPU Architecture and Models
Introduction to and History of GPU Algorithms
GPU Architecture Overview
计算机那些事(8)——图形图像渲染原理
GPU Programming Guide GeForce 8 and 9 Series
GPU的工作原理
NVIDIA显示核心列表
DirectX
高级着色器语言
探究光线追踪技术及UE4的实现
移动游戏性能优化通用技法
NV shader thread group
实时渲染深入探究
NVIDIA GPU 硬件介绍
Data Transfer Matters for GPU Computing
Slang – A Shader Compilation System
Graphics Shaders - Theory and Practice 2nd Edition
分类: C/C++/Lua, 计算机图形学
标签: GPU, shader, glsl, hlsl
NVIDIA GPU Graphics
![]() |
![]() |
|---|---|
![]() |
![]() |
NVIDIA GPU Graphics card family
NVIDIA GB202-300-A1: "GB" represents the Blackwell architecture (the next-generation architecture following Hopper and Ada Lovelace).
AI Summarized
The NVIDIA GB202‑300‑A1 is an early Blackwell‑architecture GPU variant used in the GeForce RTX 5090,
featuring a 750 mm² die, 92.2 billion transistors,
512‑bit GDDR7 memory support, and 21760 CUDA cores according to available technical listings.
Overview
The GB202‑300‑A1 is an engineering‑sample revision (A1) of NVIDIA’s flagship Blackwell‑architecture GPU.
It is the core used in the GeForce RTX 5090 and represents the top gaming‑class silicon of the Blackwell generation.
Key Specifications (from RTX 5090 implementation)
Specification Value Source
GPU Architecture Blackwell 2.0
GPU Variant GB202‑300‑A1
Transistor Count 92.2 billion
Die Size 750 mm²
CUDA / Shading Units 21760
SM Count 170
Tensor Cores 680 (5th gen)
RT Cores 170 (4th gen)
Base / Boost Clock 2017 / 2407 MHz
Memory Type GDDR7
Memory Size 32 GB
Memory Bus 512‑bit
Memory Bandwidth 1.79 TB/s
TDP ~575 W
- Manufacturer: NVIDIA
Part Number: GB202-300-A1
Product Description:
| code | description |
|---|---|
| GB202 | "202" usually refers to the top flagship core code name under this architecture (similar to AD102 used for RTX 4090 nowadays). |
| 300 | Usually refers to a specific chip version or SKU variant, possibly used to distinguish different frequencies, specifications, or testing stages. |
| A1 | Usually indicates the first revision version (Revision A1) of the engineering sample. |
GB202-300-A1 is very likely to refer to the top gaming GPU core using the Blackwell architecture.
GB202, an early engineering sample.
The corresponding consumer product is expected to be named GeForce RTX 5090 (or similar).
- Product Description (Based on Prediction)
This code name points to a GPU at the RTX 5090 level,
| code | description |
|---|---|
| Architecture | Uses the new-generation Blackwell architecture, focusing on enhancing ray tracing (Ray Tracing) and AI performance (DLSS technology will evolve to a new height). |
| Manufacturing Process | Expected to adopt TSMC's 3nm or improved 4nm process technology, achieving higher transistor density and energy efficiency ratio. |
| Memory | Likely to be equipped with faster GDDR7 memory, with a bit width possibly remaining at 384-bit or higher, and the total bandwidth will be significantly improved to meet higher resolution and data throughput requirements. |
| CUDA Cores | The number will increase significantly, possibly adopting a new SM (streaming multiprocessor) design, enhancing parallel computing capabilities. |
| Ray Tracing Cores | The 4th generation RT Cores, with a significant increase in ray tracing performance, path tracing (Path Tracing) will become a more mainstream standard for game graphics. |
| AI Cores | The 4th generation Tensor Core, providing powerful support for DLSS 3.5 and future DLSS 4, with frame generation technology and image quality reaching a new level. |
| Power Consumption | Given the performance leap, the TDP (thermal design power) is likely to continue to increase, expected to be in the range of 450W to 600W, posing higher requirements for power supply and cooling. |
- Usage Scenarios (Prediction)
This top-level GPU has very clear target users and usage scenarios:
- Extreme Gaming Experience (4K+ & 8K Gaming):
Targeted at hardcore gamers who pursue the highest quality and highest frame rates.
Can run 3A games at 8K resolution smoothly and fully enable cutting-edge graphics technologies such as path tracing.
Provide ample performance reserves for future VR/AR games. - AI Research and Development (AI Research & Development):
Although professional AI computing is dominated by NVIDIA's H-series (such as H100/B100) cards, top GeForce cards are also widely used for AI learning, model inference, and small-scale training. The powerful Tensor Core makes it an attractive choice for individual AI developers, researchers, and university laboratories. - Professional Content Creation (Professional Content Creation):
3D Rendering and Modeling: In software such as Blender, V-Ray, and Octane, GPU rendering speed will be exponentially improved.
Video Editing and Post-Production: Seamless experience for real-time editing, color correction, and effect addition of 8K or higher resolution videos.
It is particularly beneficial for users of software such as DaVinci Resolve and Adobe Premiere.
AI-assisted creation: Utilizing the powerful AI capabilities to accelerate creative workflows such as image enlargement, video frame filling, and background separation. - Tech Enthusiasts and Overclocking (Enthusiasts & Overclocking):
This chip is specifically designed for enthusiasts who pursue extreme performance. It will be a new platform for overclockers to challenge world records.
In addition to NVIDIA GB202-300-A1 , supply a wide range of other NVIDIA GPU Graphics card family . If you have any need or interest, please feel free to send inquiry to abaelhe@icloud.com














浙公网安备 33010602011771号