2.9 深入GPU硬件架构及运行机制

问题

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

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

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

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

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

5、SIMD和SIMT是什么?它们的好处是什么?co-issue呢?

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

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

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

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

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

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

12、GPU Context是什么?有什么作用?

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

回答

1、简单来说是CPU先将GPU需要用到的各种数据(例如顶点数据、渲染设置)准备好后,然后将这些数据传输给GPU,GPU接收到这些数据后在进行一系列操作。

深入了说CPU将获取到的高级语言再到汇编语言最终转换为二进制,通过MMIO将指令发给GPU,GPU将获取到的信息进行一系列操作,GPU也可以访问CPU,得到最终图像。

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

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

耦合式架构CPU与CPU共享内存,广泛应用于游戏主机里。

2、有缓存机制,5种:寄存器(registers)、L1缓存、L2缓存、纹理常量缓存(Tex,C-Cache)、系统内存(System Memory)。

以访问周期来算的话,寄存器:1,L1缓存:1~32,L2缓存:32~64,纹理、常量缓存:400~600,系统内存:400~600

3、顶点着色器(在SM中warp来执行)->曲面细分着色器->几何着色器(GS)->屏幕映射->裁剪->三角形设置->三角形遍历->片元着色器->逐片元操作。

4、Early-Z就是在片元着色器前进行一次深度测试,还会发生一次深度测试,会产生深度数据冲突的问题,解决办法就是在写入深度值前在与深度缓冲区的值进行一次比较。

5、SIMD是单指令多数据,SIMT是单指令多线程(并行数据)。

SIMD是可以对单个SM中的单个Core处理一个指令,而SIMT可对GPU中单个SM中的多个Core同时处理一个指令,并且每个Core存取的数据可以是不同的。

co-issue是为了解决SIMD运行单元无法充分利用的问题,将1D 2D 3D维度的数据合并到4D中进行计算。

6、是并行处理的,相较于CPU,GPU将运算单元细分为大量Core,统一指令下达,从而进行批量并行处理。

7、GPC(Graph Processor Clusters,图形处理簇)、TPC(Texture/Processor Clusters,纹理处理簇)、SM(Stream Multiprocessor,流多处理器),Warp(线程束)。

包含关系:GPC->TPC->SM->Warp。

在SM中以32个线程(Theard)为一组的线程束(Warp)来调度,Core是线程的执行单元,在一段时间内,一个Core可以执行一个线程,也可以切换成另一个线程。

8、可以是同一处理单元。最大化效率,将vs和ps合并为一个处理单元。

9、不是。最小单元是2*2 像素块(qual)。

原因:简化和加速像素分派的工作,精简SM的架构,减少硬件单元数量和尺寸,降低功耗,提高效能比,无效像素虽然不会被存储结果,但可辅助有效像素求导函数。

这种方式也会导致某些情况下性能损耗。

10、会。GPU以warp为单位并行计算,1warp为32个线程,warp的执行是lock-step模式,32个线程执行同样的指令(可以是不同的数据), if-else分支会导致线程的有效执行的时间长短不同,for循环条件的不同也会导致线程的有效执行时间不同,意味着整个warp32个线程的耗时都是以最长时间为准,32个线程需要等待最慢的执行完毕,因此造成了算力的浪费,降低了渲染效率。

11、左边的效率更快。

原因:(1)Vertex Fetch阶段,三角形数量少意味着需要获取的vertex data更少,更省时省带宽。(2)更多的三角形意味着更多的quad overdraw。

12、GPU Context代表了GPU计算的状态,类似于程序运行快照,含运行指令和数据状态等信息。譬如shader经过编译后推送到GPU后,GPU会以Context将指令推送到各个Core的存储空间以供执行。

在同一个ALU中,使用延迟高的缓存后导致卡顿,此时会激活第二组Context来调用ALU以便计算,当所有Context被占用完时,当第一组Context处理完毕后才会继续执行。所以Context越多就会提升运算单元的吞吐量,提高效率。

13、优化

一、GPU是什么

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

NVIDIA GPU芯片实物图

我们日常讨论GPU和显卡时,经常混为一谈,严格来说是有区别的。GPU是显卡(Video card、Display card、Graphics card)最核心的部件,但除了GPU,显卡还有散热器、通讯员兼、与主板和显示器连接的各类插槽。

二、GPU物理架构

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

当GPUI结合散热风扇、PCI插槽、HDMI接口等部件后就组成了显卡,如下图所示。

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

三、NIVDIA GPU架构历史

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

  • 2008 - Tesla
  • Tesla最初是给计算处理单元使用的,应用于早期的CUDA系列显卡芯片中,并不是真正意义上的普通图形处理芯片
  • 2010 - Fermi
  • Fermi是第一个完整的GPU计算架构。首款可支持与共享存储结合纯cache层次的GPU架构,支持ECC的GPU架构。
  • 2012 - Kepler
  • Kepler相较于Fermi更快,效率更高,性能更好。
  • 2014 - Maxwell
  • 其全新的立体像素全局光照(VXGI)技术首次让游戏GPU能够提供实时的动态全局光照效果。基于Maxwell架构的GTX 980和970 GPU采用了包括多帧采样抗锯齿(MFAA)、动态超级分辨率(DSR)、VR Direct以及超节能设计在内的一系列新技术。
  • 2016 - Pascal
  • pascal 架构将处理器和数据集成在同一个程序包内,以实现更高的计算效率。1080系列、1060系列基于Pascal架构。
  • 2017 - Volta
  • Volta 配备640个Tensor核心,每秒可提供成果100兆次浮点运算(TFLOPS)的深度学习效能,比前一代的Pascal架构快5倍以上。
  • 2018 - Turing
  • Turing架构配备了名为RTCore的专用光线追踪处理器,能够以高达每秒10 Giga Rays的速度对光线和声音在3D环境中的传播进行加速计算。Turing架构将实施光线追踪运算加速至上一代NVIDIA Pascal架构的25倍,并能以搞出CPU 30多倍的速度进行电影效果的最终帧渲染。2060系列、2080系列显卡也是跳过了Volta直接选择了Turing架构

四、GPU微观物理结构

1.NVIDIA Tesla架构

  • 拥有7组TPC(Texture/Processor Cluster,纹理处理簇)
  • 每个TPC有两组SM(Stream Multiprocessor,流多处理器)
  • 每个SM包含:
  • 8个SP(Streaming Processor,流处理器)
  • 2个SFU(Special Function Unit,特殊函数单元)
  • L1缓存、MT Issue(多线程指令获取)、C-Cache(常量缓存)、共享内存
  • 除了TPC核心单元,还有与显存、CPU、系统内存交互的各种部件

2.NVIDIA Fermi架构

  • 拥有16个SM
  • 2个Warp Scheduler(线程束)
  • 两组共32个Core
  • 16组加载存储单元(LD/ST)
  • 4个特殊函数单元(SFU)
  • 分发单元(Dispatch Unit)
  • 每个Core:
  • 1个FPU(浮点数单元)
  • 1个ALU(逻辑运算单元)

3.NIVDIA Maxwell架构

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

4.NVIDIA Turing架构

  • 6个GPC(图形处理簇)
  • 36个TPC(纹理处理簇)
  • 72个SM(流多处理器)
  • 每个GPC有6个TPC,每个TPC有2个SM
  • 4608 个CUDA核
  • 72个RT核
  • 576个Tensor核
  • 288个纹理单元
  • 12*32位 GDDR6内存控制器(共384位)

Turing每个SM的结构图如下:

每个SM包含:

  • 64个CUDA核
  • CUDA是NVIDIA推出的统一计算架构
  • 8个Tensor核
  • Tensor COre是专门为执行向量或矩阵运算而设计的专门执行单元
  • 256KB寄存器文件

5.GPU架构的共性

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

    • GPC(图形处理簇)
    • TPC(纹理处理簇)
    • Thread(线程)
    • SM、SMX、SMM(Stream Multiprocessor,流多处理器)
    • Warp线程束、Warp Scheduler(Warp编排器)
    • SP(Streaming Processor,流处理器)
    • Core(执行数学运算的核心)
    • ALU(逻辑运算单元)
    • FPU(浮点数单元)
    • SFU(特殊函数单元)
    • ROP(render output unit,渲染输入单元)
    • Load/Store Unit(加载存储单元)
    • L1 Cache(L1缓存)
    • L2 Cache(L2缓存)
    • Shared Memory(共享内存)
    • Register File(寄存器)

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

6.核心组件架构

    • 包含关系 GPC-->TPC-->SM-->CORE
    • SM中包含Poly Morph Engine(多边形引擎)、L1 Cache(L1缓存)、Shared Memory(共享内存)、Core(执行数学运算的核心)等
    • CORE中包含ALU、FPU、Execution Context(执行上下文)、(Detch)、解码(Decode)

7.GPU渲染总览(Fermi架构)

Fermi架构的运行机制总览图:

从Fermi开始NVIDIA使用类似的原理架构,使用一个Giga Thread Engine来管理所有正在进行的工作,GPU被划分成多个GPCs(Graphics Processing Cluster),每个GPC拥有多个SM(SMX、SMM)和一个光栅化引擎(Raster Engine),它们其中有很多的连接,最显著的是Crossbar,它可以连接GPCs和其他功能性模块(例如ROP或其他子系统)。

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

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

8.GPU逻辑管线

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

  1. 程序通过图形API(DX、GL、WEBGL)发出drawcall指令,指令会被推送到驱动程序,驱动会检查指令的合法性,然后把指令放到GPU可以读取的Pushbuffer中。
  2. 经过一段时间或者显示调用flush指令后,驱动程序把Pushbuffer的内容发送给GPU,GPU通过主机接口(Host Interface)接受这些命令,并通过前端(Front End)处理这些命令。
  3. 再图元分配器(Primitive Distributor)中开始工作分配,处理indexbuffer中的顶点产生三角形分成批次(batches),然后发送给多个GPCs。这一步的理解就是提交上来n个三角形,分配给这几个GPC同时处理。

  1. 在GPC中,每个SM中的Poly Morph Engine负责通过三角形索引(triangle indices)取出三角形的数据(vertex data),即图中的Vertex Fetch模块。
  2. 在获取数据之后,在SM中以32个线程为一组的线程束(Warp)来调度,来梳理顶点数据。Warp是典型的单指令多线程(SIMT,SIMD单指令多数据的升级)的实现,也就是32个线程同时执行的指令是一模一样的,只是线程数据不一样,这样的好处就是一个warp只需要一套逻辑对指令进行解码和执行就可以了,芯片可以做的更小更快,之所以这么多是由于GPU需要处理的任务是天然并行的。
  3. SM的warp调度器会按照顺序分发指令给整个warp,单个warp中的线程会锁步(locak-step)执行各自的指令,如果线程碰到不激活执行的情况也会被遮掩(be masked out)。被遮掩的原因有很多,例如当前的指令是if(true)的分支,但是当前线程的数据的条件是false,或者循环的次数不一样(比如for循环次数n不是常量,或被break提前终止了但是别的还在走),因此在shader中的分支会显著增加时间消耗,在一个warp中的分支除非32个现成都走到if或者else里面,否则相当于所有的分支都走了一遍,现成不能独立执行指令而是以warp为单位,而这些warp之间才是独立的。
  4. warp中的指令可以被一次完成,也可能经过多次调度,例如通常SM中的LD/ST(加载存取)单元数量明显少于基础数学操作单元。
  5. 由于某些指令比其他指令需要更长时间才能完成,特别是内存加载,warp调度器可能会简单的切换到另一个 没有内存等待的warp,这是GPU如何克服内存读取延迟的关键,只是简单的切换活动线程组。为了是这种切换非常快,调度器管理的所有warp在寄存器文件中都有自己的寄存器。这里就会有个矛盾产生,shader需要更多的寄存器,就会给warp留下越少的空间,就会产生越少的warp,这时候在碰到内存延迟的会后就会只是等待,而没有可以运行的warp可以切换。

  1. 一旦warp完成了vertex-shader的所有指令,运算结果会被Viewport Transform模块处理,三角形会被裁剪然后准备栅格化,GPU会使用L1和L2缓存来进行vertex-shader和pixel-shader的数据通信。

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

  1. SM上的Attribute Setup保证了从vertex-shader来的数据经过差值后是pixel-shader是可读的。
  2. GPC上的光栅引擎(raster engines)在它被接收到的三角形上工作,来负责这些三角形的像素信息的生成(同时会处理裁剪Clipping、背面剔除和Early-Z剔除)。
  3. 32个像素线程将被分成一组,或者说8个2x2的像素快,这是在像素着色器上面的最小工作单元,在这个像素线程内,如果没有被三角形覆盖就会被遮掩,SM中的warp调度器会管理像素着色器的任务。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值