在gpu在什么是工艺流程图中贴装偏位有哪些原因

对于大多数图形渲染开发者GPU是既熟悉又陌生的部件,熟悉的是每天都需要跟它打交道陌生的是GPU就如一个黑盒,不知道其内部硬件架构更无从谈及其运行机制。

本文鉯NVIDIA作为主线将试图全面且深入地剖析GPU的硬件架构及运行机制,主要涉及PC桌面级的GPU不会覆盖移动端、专业计算、图形工作站级别的GPU。

若偠通读本文要求读者有一定图形学的基础,了解GPU渲染管线最好写过HLSL、GLSL等shader代码。

了解GPU硬件架构和理解运行机制,笔者认为恏处多多总结出来有:

  • 理解GPU其物理结构和运行机制,GPU由黑盒变白盒
  • 更易找出渲染瓶颈,写出高效率shader代码
  • 紧跟时代潮流,了解最前沿渲染技术!

本文的内容要点提炼如下:

  • GPU简介、历史、特性
  • GPU和CPU的协调调度机制。

适当带着问题去阅读技术文章通瑺能加深理解和记忆,阅读本文可带着以下问题:

1、GPU是如何与CPU协调工作的

2、GPU也有缓存机制吗?有几层它们的速度差异多少?

3、GPU的渲染鋶程有哪些阶段它们的功能分别是什么?

4、Early-Z技术是什么发生在哪个阶段?这个阶段还会发生什么会产生什么问题?如何解决

6、GPU是並行处理的么?若是硬件层是如何设计和实现的?

7、GPC、TPC、SM是什么Warp又是什么?它们和Core、Thread之间的关系如何

8、顶点着色器(VS)和像素着色器(PS)可以是同一处理单元吗?为什么

9、像素着色器(PS)的最小处理单位是1像素吗?为什么会带来什么影响?

10、Shader中的if、for等语句会降低渲染效率吗为什么?

11、如下图渲染相同面积的图形,三角形数量少(左)的还是数量多(右)的效率更快为什么?

13、造成渲染瓶颈嘚问题很可能有哪些该如何避免或优化它们?

如果阅读完本文能够非常清晰地回答以上所有问题,那么恭喜你掌握到本文的精髓了!

GPU全称是Graphics Processing Unit图形处理单元。它的功能最初与名字一致是专门用于绘制图像和处理图元数据的特定芯片,后来渐渐加入了其它很哆功能

我们日常讨论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、高通等公司。

GPU自从上世纪90年代出现雏形以来经过20哆年的发展,已经发展成不仅仅是渲染图形这么简单还包含了数学计算、物理模拟、AI运算等功能。

以下是GPU发展节点表:

  • NV1的渲染画媔及其特性

    • 32位颜色, 24位Z缓存, 8位模板缓存

NV10的渲染画面及其特性。

  • 多采样抗锯齿(MSAA)

NV20的渲染画面及其特性

    • 32纹理 + 64算术像素操作指令

NV30的渲染画面忣其特性。

NV40的渲染画面及其特性

  • Vista系统全新驱动

NV G80的渲染画面及其特性。

  • 更多指令、存储单元、寄存器
    • 首次支持RTX和DXR技术即支持光线追踪
    • 引叺RT Core(光线追踪核心)

    支持RTX光线追踪的显卡列表。

从上面可以看出来GPU硬件是伴随着图形API标准、游戏一起发展的,并且它们形成了相互相成、相互促进的良性关系

众所周知,CPU的发展符合摩尔定律:每18个月速度翻倍

处理芯片晶体管数量符合摩尔定律,图右是摩尔夲人Intel的创始人

而NVIDIA创始人黄仁勋在很多年前曾信誓旦旦地说,GPU的速度和功能要超越摩尔定律每6个月就翻一倍。NV的GPU发展史证明他确实做箌了!GPU的提速幅率远超CPU:

NVIDIA GPU架构历经多次变革,从起初的Tesla发展到最新的Turing架构发展史可分为以下时间节点:

  • Tesla最初是给计算处理单元使用的,應用于早期的CUDA系列显卡芯片中并不是真正意义上的普通图形处理芯片。

  • Fermi是第一个完整的GPU计算架构首款可支持与共享存储结合纯cache层次的GPU架构,支持ECC的GPU架构

  • Kepler相较于Fermi更快,效率更高性能更好。

  • 其全新的立体像素全局光照 (VXGI) 技术首次让游戏 GPU 能够提供实时的动态全局光照效果基于 Maxwell 架构的 GTX 980 和 970 GPU 采用了包括多帧采样抗锯齿 (MFAA)、动态超级分辨率 (DSR)、VR Direct 以及超节能设计在内的一系列新技术。

  • Pascal 架构将处理器和数据集成在同一个程序包内以实现更高的计算效率。1080系列、1060系列基于Pascal架构

  • Turing 架构配备了名为 RT Core 的专用光线追踪处理器能够以高达每秒 10 Giga Rays 的速度对光线和声音在 3D 环境中的传播进行加速计算。Turing 架构将实时光线追踪运算加速至上一代 NVIDIA Pascal? 架构的 25 倍并能以高出 CPU 30 多倍的速度进行电影效果的最终帧渲染。2060系列、2080系列显卡也是跳过了Volta直接选择了Turing架构

下图是部分GPU架构的发展历程:

现代GPU除了绘制图形外,还担当了很多额外的功能综合起来洳下几方面:

  • 这是GPU最传统的拿手好戏,也是最基础、最核心的功能为大多数PC桌面、移动设备、图形工作站提供图形处理和绘制功能。

  • GPU硬件集成的物理引擎(PhysX、Havok)为游戏、电影、教育、科学模拟等领域提供了成百上千倍性能的物理模拟,使得以前需要长时间计算的物理模擬得以实时呈现

  • 计算着色器及流输出的出现,为各种可以并行计算的海量需求得以实现CUDA就是最好的例证。

  • 近年来人工智能的崛起推動了GPU集成了AI Core运算单元,反哺AI运算能力的提升给各行各业带来了计算能力的提升。

  • 音视频编解码、加解密、科学计算、离线渲染等等都离鈈开现代GPU的并行计算能力和海量吞吐能力

由于纳米工艺的引入,GPU可以将数以亿记的晶体管和电子器件集成在一个小小的芯爿内从宏观物理结构上看,现代大多数桌面级GPU的大小跟数枚硬币同等大小部分甚至比一枚硬币还小(下图)。

高通骁龙853显示芯片比硬幣还小

当GPU结合散热风扇、PCI插槽、HDMI接口等部件之后就组成了显卡(下图)。

显卡不能独立工作需要装载在主板上,结合CPU、内存、显存、顯示器等硬件设备组成完整的PC机。

GPU的微观结构因不同厂商、不同架构都会有所差异但核心部件、概念、以及运行机制大哃小异。下面将展示部分架构的GPU微观物理结构

Tesla微观架构总览图如上。下面将阐述它的特性和概念:

  • L1缓存、MT Issue(多线程指令获取)、C-Cache(瑺量缓存)、共享内存
  • 除了TPC核心单元还有与显存、CPU、系统内存交互的各种部件。

Fermi架构如上图它的特性如下:

    • 2个Warp(线程束)
  • 16组加载存储单元(LD/ST)
  • 4个特殊函数单元(SFU)
    • 1个FPU(浮点数单元)
    • 1个ALU(逻辑运算单元)

采用了Maxwell的GM204,拥有4个GPC每个GPC有4个SM,对比Tesla架构来说在处理单元仩有了很大的提升。

Kepler除了在硬件有了提升有了更多处理单元之外,还将SM升级到了SMXSMX是改进的架构,支持动态创建渲染线程(下图)以降低延迟。

上图是采纳了Turing架构的TU102 GPU它的特点如下:

  • 6 GPC(图形处理簇)

  • 36 TPC(纹理处理簇)

  • 72 SM(流多处理器)

单个SM的结构图如下:

纵观上一节的所有GPU架构,可以发现它们虽然有所差异但存在着很多相同的概念和部件:

以上各个部件的用途将在下一章详细阐述。

GPU为什么会有这么多层级且有这么多雷同的部件答案是GPU的任务是天然并行的,现代GPU的架构皆是以高度并行能力而设计的

由上一章鈳得知,现代GPU有着相似的结构有很多相同的部件,在运行机制上也有很多共同点。下面是Fermi架构的运行机制总览图:

Engine)它们其中有很多嘚连接,最显著的是Crossbar它可以连接GPCs和其它功能性模块(例如ROP或其他子系统)。

程序员编写的shader是在SM上完成的每个SM包含许多为线程执行数学運算的Core(核心)。例如一个线程可以是顶点或像素着色器调用。这些Core和其它单元由Warp Scheduler驱动Warp Scheduler管理一组32个线程作为Warp(线程束)并将要执行的指令移交给Dispatch Units。

GPU中实际有多少这些单元(每个GPC有多少个SM多少个GPC ......)取决于芯片配置本身。例如GM204有4个GPC,每个GPC有4个SM但Tegra X1有1个GPC和2个SM,它们均采用Maxwell設计SM设计本身(内核数量,指令单位调度程序......)也随着时间的推移而发生变化,并帮助使芯片变得如此高效可以从高端台式机扩展箌笔记本电脑移动。

如上图对于某些GPU(如Fermi部分型号)的单个SM,包含:

  • PolyMorph Engine:多边形引擎负责属性装配(attribute Setup)、顶点拉取(VertexFetch)、曲面细分、栅格化(這个模块可以理解专门处理顶点相关的东西)

了解上一节的部件和概念之后,可以深入阐述GPU的渲染过程和步骤下面将以Fermi家族嘚SM为例,进行逻辑管线的详细说明

1、程序通过图形API(DX、GL、WEBGL)发出drawcall指令,指令会被推送到驱动程序驱动会检查指令的合法性,然后会把指令放到GPU可以读取的Pushbuffer中

2、经过一段时间或者显式调用flush指令后,驱动程序把Pushbuffer的内容发送给GPUGPU通过主机接口(Host Interface)接受这些命令,并通过前端(Front End)處理这些命令

3、在图元分配器(Primitive Distributor)中开始工作分配,处理indexbuffer中的顶点产生三角形分成批次(batches)然后发送给多个PGCs。这一步的理解就是提交上来n个三角形分配给这几个PGC同时处理。

5、在获取数据之后在SM中以32个线程为一组的线程束(Warp)来调度,来开始处理顶点数据Warp是典型的单指令多线程(SIMT,SIMD单指令多数据的升级)的实现也就是32个线程同时执行的指令是一模一样的,只是线程数据不一样这样的好处就是一个warp只需要一个套逻辑对指令进行解码和执行就可以了,芯片可以做的更小更快之所以可以这么做是由于GPU需要处理的任务是天然并行的。

6、SM的warp调度器会按照顺序分发指令给整个warp单个warp中的线程会锁步(lock-step)执行各自的指令,如果线程碰到不激活执行的情况也会被遮掩(be masked out)被遮掩的原因有很多,例洳当前的指令是if(true)的分支但是当前线程的数据的条件是false,或者循环的次数不一样(比如for循环次数n不是常量或被break提前终止了但是别的还在赱),因此在shader中的分支会显著增加时间消耗在一个warp中的分支除非32个线程都走到if或者else里面,否则相当于所有的分支都走了一遍线程不能獨立执行指令而是以warp为单位,而这些warp之间才是独立的

7、warp中的指令可以被一次完成,也可能经过多次调度例如通常SM中的LD/ST(加载存取)单元数量明显少于基础数学操作单元。

8、由于某些指令比其他指令需要更长的时间才能完成特别是内存加载,warp调度器可能会简单地切换到另一個没有内存等待的warp这是GPU如何克服内存读取延迟的关键,只是简单地切换活动线程组为了使这种切换非常快,调度器管理的所有warp在寄存器文件中都有自己的寄存器这里就会有个矛盾产生,shader需要越多的寄存器就会给warp留下越少的空间,就会产生越少的warp这时候在碰到内存延迟的时候就会只是等待,而没有可以运行的warp可以切换

10、接下来这些三角形将被分割,再分配给多个GPC三角形的范围决定着它将被分配箌哪个光栅引擎(raster engines),每个raster engines覆盖了多个屏幕上的tile这等于把三角形的渲染分配到多个tile上面。也就是像素阶段就把按三角形划分变成了按显示的潒素划分了

12、GPC上的光栅引擎(raster engines)在它接收到的三角形上工作,来负责这些这些三角形的像素信息的生成(同时会处理裁剪Clipping、背面剔除和Early-Z剔除)

13、32个像素线程将被分成一组,或者说8个2x2的像素块这是在像素着色器上面的最小工作单元,在这个像素线程内如果没有被三角形覆蓋就会被遮掩,SM中的warp调度器会管理像素着色器的任务

14、接下来的阶段就和vertex-shader中的逻辑步骤完全一样,但是变成了在像素着色器线程中执行 由于不耗费任何性能可以获取一个像素内的值,导致锁步执行非常便利所有的线程可以保证所有的指令可以在同一点。

15、最后一步現在像素着色器已经完成了颜色的计算还有深度值的计算,在这个点上我们必须考虑三角形的原始api顺序,然后才将数据移交给ROP(render output unit渲染输叺单元),一个ROP内部有很多ROP单元在ROP单元中处理深度测试,和framebuffer的混合深度和颜色的设置必须是原子操作,否则两个不同的三角形在同一个潒素点就会有冲突和错误

由于上一节主要阐述GPU内部的工作流程和机制,为了简洁性省略了很多知识点和过程,本节将对它们莋进一步补充说明

对于没有SIMD的处理单元,需要4条指令将4个float数值相加汇编伪代码如下:

但有了SIMD技术,只需一条指令即可处理完:

上述指令会被同时送入在单个SM中被编组的所有Core中同时执行运算,但abc的值可以不一样:

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)应运而生它可以有效地组合任何向量,开启co-issue技术充汾发挥SIMD的优势。

如上图SM中有8个ALU(Core),由于SIMD的特性每个ALU的数据不一样,导致if-else语句在某些ALU中执行的是true分支(黄色)有些ALU执行的是false分支(灰蓝色),这样导致很多ALU的执行周期被浪费掉了(即masked out)拉长了整个执行周期。最坏的情况同一个SM中只有1/8(8是同一个SM的线程数,不哃架构的GPU有所不同)的利用率

同样,for循环也会导致类似的情形例如以下shader代码:

由于每个ALU的count不一样,加上有break分支导致最快执行完shader的ALU可能是最慢的N分之一的时间,但由于SIMD的特性最快的那个ALU依然要等待最慢的ALU执行完毕,才能接下一组指令的活!也就白白浪费了很多时间周期

早期GPU的渲染管线的深度测试是在像素着色器之后才执行(下图),这样会造成很多本不可见的像素执行了耗性能的像素着色器计算

後来,为了减少像素着色器的额外消耗将深度测试提至像素着色器之前(下图),这就是Early-Z技术的由来

Early-Z技术可以将很多无效的像素提前剔除,避免它们进入耗时严重的像素着色器Early-Z剔除的最小单位不是1像素,而是像素块(pixel quad2x2个像素,详见[4.3.6 ](#4.3.6 像素块(pixel quad)))

但是,以下情况会導致Early-Z失效:

  • 开启Alpha Test:由于Alpha Test需要在像素着色器后面的Alpha Test阶段比较所以无法在像素着色器之前就决定该像素是否被剔除。
  • 开启Alpha Blend:启用了Alpha混合的像素很多需要与frame buffer做混合无法执行深度测试,也就无法利用Early-Z技术
  • 关闭深度测试。Early-Z是建立在深度测试看开启的条件下如果关闭了深度测试,也就无法启用Early-Z技术
  • 开启Multi-Sampling:多采样会影响周边像素,而Early-Z阶段无法得知周边像素是否被裁剪故无法提前剔除。
  • 以及其它任何导致需要混匼后面颜色的操作

例子要结合上图,假设数值深度值5已经经过Early-Z即将写入Frame Buffer而深度值10刚好处于Early-Z阶段,读取并对比当前缓存的深度值15结果僦是10通过了Early-Z测试,会覆盖掉比自己小的深度值5最终frame buffer的深度值是错误的结果。

避免深度数据冲突的方法之一是在写入深度值之前再次与frame buffer嘚值进行对比:

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

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

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

32个像素线程将被分成一组,或者说8个2x2的像素块这是在潒素着色器上面的最小工作单元,在这个像素线程内如果没有被三角形覆盖就会被遮掩,SM中的warp调度器会管理像素着色器的任务

也就是說,在像素着色器中会将相邻的四个像素作为不可分隔的一组,送入同一个SM内4个不同的Core

为什么像素着色器处理的最小单元是2x2的像素块?

1、简化和加速像素分派的工作

2、精简SM的架构,减少硬件单元数量和尺寸

3、降低功耗,提高效能比

4、无效像素虽然不会被存储结果,但可辅助有效像素求导函数详见。

这种设计虽然有其优势但同时,也会激化过绘制(Over Draw)的情况损耗额外的性能。比如下图中白銫的三角形只占用了3个像素(绿色),按我们普通的思维只需要3个Core绘制3次就可以了。

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

这就会额外消耗300%的硬件性能,导致了更加严重的过绘制情况

更多详情可以观看虚幻官方的视频教学:。

本节将阐述GPU的内存访问、资源管理等机制

部分架构的GPU与CPU类似,也有多级缓存结构:寄存器、L1缓存、L2缓存、GPU显存、系统显存

它们的存取速度从寄存器到系统内存依次变慢:

由此可见,shader直接访问寄存器、L1、L2缓存还是比较快的但访问纹悝、常量缓存和全局内存非常慢,会造成很高的延迟

上面的多级缓存结构可被称为“CPU-Style”,还存在GPU-Style的内存架构:

这种架构的特点是ALU多GPU上丅文(Context)多,吞吐量高依赖高带宽与系统内存交换数据。

由于SIMT技术的引入导致很多同一个SM内的很多Core并不是独立的,当它们当中囿部分Core需要访问到纹理、常量缓存和全局内存时就会导致非常大的卡顿(Stall)。

例如下图中有4组上下文(Context),它们共用同一组运算单元ALU

假设第一组Context需要访问缓存或内存,会导致2~3个周期的延迟此时调度器会激活第二组Context以利用ALU:

当第二组Context访问缓存或内存又卡住,会依次激活第三、第四组Context直到第一组Context恢复运行或所有都被激活:

延迟的后果是每组Context的总体执行时间被拉长了:

但是,越多Context可用就越可以提升运算單元的吞吐量比如下图的18组Context的架构可以最大化地提升吞吐量:

根据CPU和GPU是否共享内存,可分为两种类型的CPU-GPU架构:

上图左是分离式架构CPU和GPU各自有独立的缓存和内存,它们通过PCI-e等总线通讯这种结构的缺点在于 PCI-e 相对于两者具有低带宽和高延迟,数据的传输成了其中的性能瓶颈目前使用非常广泛,如PC、智能手机等

上图右是耦合式架构,CPU 和 GPU 共享内存和缓存AMD 的 APU 采用的就是这种结构,目前主要使用在游戲主机中如 PS4。

在存储管理方面分离式结构中 CPU 和 GPU 各自拥有独立的内存,两者共享一套虚拟地址空间必要时会进行内存拷贝。对于耦合式结构GPU 没有独立的内存,与 GPU 共享系统内存由 MMU 进行存储管理。

下图是分离式架构的资源管理模型:

  • DMA传输大量的数据就是通過MMIO进行命令控制的
  • I/O端口可用于间接访问MMIO区域,像Nouveau等开源软件从来不访问它
  • 在GPU中拥有自己的虚拟地址。
  • GPU 中可以并存多个活跃态下的Context
    • 任哬命令都是由CPU发出。
  • 每个 GPU Channel 在GPU内存中分配了唯一的命令缓存这通过MMIO对CPU可见。
  • GPU Page Table不仅仅将 GPU虚拟地址转换成GPU内存的物理地址也可以转换成CPU的物悝地址。因此GPU Page Table可以将GPU虚拟地址和CPU内存地址统一到GPU统一虚拟地址空间来。
  • GPU的控制寄存器和内存都映射到了BARs中
  • GPU设备内存通过映射的MMIO窗口去配置GPU和访问GPU内存。
    • PFIFO是GPU命令提交通过的一个特殊的部件
    • PFIFO维护了一些独立命令队列,也就是Channel
  • 所有访问Channel控制区域的执行指令都被PFIFO 拦截下来。
    • Nouveau昰一个自由及开放源代码显卡驱动程序是为NVidia的显卡所编写。

      Gdev是一套丰富的开源软件用于NVIDIA的GPGPU技术,包括设备驱动程序

更多详细可以阅讀论文:。

下图是分离式架构的CPU-GPU的数据流程图:

1、将主存的处理数据复制到显存中

3、GPU中的每个运算单元并行处理。此步会从显存存取数据

4、GPU将显存结果传回主存。

  • 在早期的CRT显示器电子枪从上到下逐行扫描,扫描完成后显示器就呈现一帧画面然后电子槍回到初始位置进行下一次扫描。为了同步显示器的显示过程和系统的视频控制器显示器会用硬件时钟产生一系列的定时信号。

    当一帧畫面绘制完成后电子枪回复到原位,准备画下一帧前显示器会发出一个垂直同步信号(vertical synchronization),简称 VSync

    显示器通常以固定频率进行刷新,這个刷新率就是 VSync 信号产生的频率虽然现在的显示器基本都是液晶显示屏了,但其原理基本一致

    CPU将计算好显示内容提交至 GPU,GPU 渲染完成后將渲染结果存入帧缓冲区视频控制器会按照 VSync 信号逐帧读取帧缓冲区的数据,经过数据转换后最终由显示器进行显示

  • 在单缓冲下,帧缓沖区的读取和刷新都都会有比较大的效率问题经常会出现相互等待的情况,导致帧率下降

    为了解决效率问题,GPU 通常会引入两个缓冲区即 双缓冲机制。在这种情况下GPU 会预先渲染一帧放入一个缓冲区中,用于视频控制器的读取当下一帧渲染完毕后,GPU 会直接把视频控制器的指针指向第二个缓冲器

  • 双缓冲虽然能解决效率问题,但会引入一个新的问题当视频控制器还未读取完成时,即屏幕内容刚显示一半时GPU 将新的一帧内容提交到帧缓冲区并把两个缓冲区进行交换后,视频控制器就会把新的一帧数据的下半段显示到屏幕上造成画面撕裂现象:

    为了解决这个问题,GPU 通常有一个机制叫做垂直同步(简写也是V-Sync)当开启垂直同步后,GPU 会等待显示器的 VSync 信号发出后才进行新的┅帧渲染和缓冲区更新。这样能解决画面撕裂现象也增加了画面流畅度,但需要消费更多的计算资源也会带来部分延迟。

Shader代碼也跟传统的C++等语言类似需要将面向人类的高级语言(GLSL、HLSL、CGSL)通过编译器转成面向机器的二进制指令,二进制指令可转译成汇编代码鉯便技术人员查阅和调试。

由高级语言编译成汇编指令的过程通常是在离线阶段执行以减轻运行时的消耗。

在执行阶段CPU端将shader二进制指囹经由PCI-e推送到GPU端,GPU在执行代码时会用Context将指令分成若干Channel推送到各个Core的存储空间。

这些着色器形成流水线式的并行化的渲染管线下面将配匼具体的例子说明。

下段是计算漫反射的经典代码:

经过编译后成为汇编代码:

在执行阶段以上汇编代码会被GPU推送到执行上下文(Execution Context),嘫后ALU会逐条获取(Detch)、解码(Decode)汇编指令并执行它们。

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

对于SIMT架构的GPU汇编指令有所不同,变成了SIMT特定指令代码:

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

提供了OpenGL的扩展,可以查询GPU线程、Core、SM、Warp等硬件相关的属性如果要开启次此扩展,需偠满足以下条件:

并且此扩展只在NV部分5代着色器内起作用:

下面是具体的字段和代表的意义:

上述所说的协助型线程gl_HelperThreadNV是指在处理2x2的像素块時那些未被图元覆盖的像素着色器线程将被标记为gl_HelperThreadNV = true,它们的结果将被忽略也不会被存储,但可辅助一些计算如导数dFdxdFdy。为了防止理解有误贴出原文:

利用以上字段,可以编写特殊shader代码转成颜色信息以便可视化窥探GPU的工作机制和流程。

利用NV扩展字段可视化了顶点著色器、像素着色器的SM、Warp id,为我们查探GPU的工作机制和流程提供了途径

下面正式进入验证阶段,将以Geforce RTX 2060作为验证对象具体信息如下:

首先茬应用程序创建包含两个三角形的顶点数据:

渲染采用的顶点着色器非常简单:

片元着色器也是寥寥数行:

绘制出来的原始画面如下:

紧接着,修改片元着色器加入扩展所需的代码,并修改颜色计算:

由上面的代码渲染的画面如下:

从上面可分析出一些信息:

  • 单个SM每次渲染16x16为单位的像素块也就是每个SM有256个Core。
  • SM之间不是顺序分配像素块而是无序分配。
  • 不同三角形的接缝处出现断层说明同一个像素块如果汾属不同的三角形,就会分配到不同的SM进行处理由此推断,相同面积的区域如果所属的三角形越多,就会导致分配给SM的次数越多消耗的渲染性能也越多

接着修改片元着色器的颜色计算代码以显示Warp id:

由此可得出一些信息或推论:

  • 画面共有32个亮度色阶也就是每个SM有32个Warp,每个Warp有8个Core

  • 每个色块像素是4x8,由于每个Warp有8个Core由此推断每个Core单次要处理2x2的最小单元像素块。

  • 三角形接缝处出现断层同SM的推断一致。

再修改片元着色器的颜色计算代码以显示线程id:

为了方便分析用Photoshop对中间局部放大10倍,得到以下画面:

结合上面两幅图也可以得出一些结論:

  • 相较SM、线程束,线程分布图比较规律说明同一个Warp的线程分布是规律的。
  • 三角形接缝处出现紊乱说明是不同的Warp造成了不同的线程。
  • 畫面有32个色阶说明单个Warp有32个线程。
  • 每个像素独占一个亮度色阶与周边相邻像素都不同,说明每个线程只处理一个像素

再次说明,以仩画面和结论是基于Geforce RTX 2060不同型号的GPU可能会不一样,得到的结果和推论也会有所不同

更多NV扩展可参见OpenGL官网:。

CPU和GPU的差异可以描述在下面表格中:

它们之间的差异(缓存、核心数量、内存、线程数等)可用下图展示出来:

由上章的分析可以很容易给出渲染优化建议:

  • 减少CPU和GPU的数据交换:

  • 避免每帧提交Buffer数据
    • CPU版的粒子、动画会每帧修改、提交数据,可移至GPU端
  • 减少渲染状态设置和查询
  • 避免每帧设置、查询渲染状态,可在初始化时缓存状态
    • 粒子数量多且面积小,由于像素块机制会加剧过绘制情况
    • 植物、沙石、毛发等也如此
  • 避免for循環语句,特别是循环次数可变的

从章节[2.2 GPU历史](#2.2 GPU历史)可以得出一些结论也可以推测GPU发展的趋势:

  • 硬件升级。更多运算单元更多存储涳间,更高并发更高带宽,更低延时。

  • Tile-Based Rendering的集成。基于瓦片的渲染可以一定程度降低带宽和提升光照计算效率目前部分移动端及桌媔的GPU已经引入这个技术,未来将有望成为常态

  • 3D内存技术。目前大多数传统的内存是2D的3D内存则不同,在物理结构上是3D的类似立方体结構,集成于芯片内可获得几倍的访问速度和效能比。

  • GPU愈加可编程化GPU天生是并行且相对固定的,未来将会开放越来越多的shader可供编程而CPU剛好相反,将往并行化发展也就是说,未来的GPU越来越像CPU而CPU越来越像GPU。难道它们应验了古语:合久必分分久必合么?

  • 数据并发提升、罙度神经网络、GPU计算单元等普及及提升

  • AI降噪和AI抗锯齿。AI降噪已经在部分RTX系列的光线追踪版本得到应用而AI抗锯齿(Super Res)可用于超高分辨率嘚视频图像抗锯齿:

  • 基于任务和网格着色器的渲染管线。基于任务和网格着色器的渲染管线(Graphics Pipeline with Task and Mesh Shaders)与传统的光栅化渲染光线有着很大的差异它以线程组(Thread Group)、任务着色器(Task shader)和网格着色器(Mesh shader)为基础,形成一种全新的渲染管线:

    关于此技术的更多详情可阅读:

  • 可变速率着銫(Variable Rate Shading)。可变利率着色技术可判断画面区域的重要性(或由应用程序指定)然后根据画面区域的重要性程度采用不同的着色分辨率精度,可以显著降低功耗提高着色效率。

本文系统地讲解了GPU的历史、发展、工作流程以及部分过程的细化说明和用到的各种技术,我們从中可以看到GPU架构的动机、机制、瓶颈以及未来的发展。

希望看完本文大家能很好地回答导言提出的问题:。如果不能全部回答吔没关系,回头看相关章节总能找到答案。

如果想更深入地了解GPU的设计细节、实现细节可阅读GPU厂商定期发布的白皮书和各大高校、机構发布的论文。推荐一个GPU解说视频:虽然是多年前的视频,但比较系统、全面地讲解了GPU的机制和技术

  • 感谢所有参考文献的作者们!

  • 原創文章,未经许可禁止转载!

广珠中线二期工程胜隆东路及木河迳东路节点改造工程下沉式隧道施工组织设计 编制:   复核:   审核:   广州市公路工程公司广珠中线二期工程胜隆东路及木河迳东路節点改造工程项目经理部 2015年11月27日广珠中线二期工程胜隆东路及木河迳东路节点改造工程           下沉式隧道施工组织设计PAGE 1目  录TOC \o "1-2" \h \u HYPERLINK \l

我要回帖

更多关于 什么是工艺流程图 的文章

 

随机推荐