GPU架构演化史5 2006-2010 统一着色器带来初代CUDA
前言
在Vertex Shader和Pixel Shader都可编程了以后,GeForce 6 到 GeForce 7的过程中,如何平衡VS和PS的算力也成了一个问题,由于处理的Fragments的像素要比Vertex多很多,通常PS和VS的数量比是3:1,如下图GeForce 7所示
虽然当时有很多游戏是PS Heavy的,但是不同的渲染场景带来的不平衡的问题还是很严重,例如在曲面过多的复杂场景中,三角形的数量激增导致PS空转
当然为了解决VS或者PS不够用的问题,学当年3Dfx单卡堆双芯片和四卡SLI的技巧也用上了,例如下图的GeForce 7950 GX2 Quad-SLI
而另一方面在可编程能力上逐渐又有一些算法要求在图元(Primitive)上支持可编程,也就是Geometry Shader(GS)的需求被提出来。
于是工业界基本上都在开始思考Unified Shader的实现。
接下来的几年,逐渐诞生了nVidia G8X、ATI R700这样的Unified Shader的架构,中途还有Intel Larrabee这样的架构,然后再进一步最终这些又演进成了CUDA、GCN和Intel Xeon Phi等高性能计算平台。
在这个变革中期,SIGGRAPH有一个系列讲座 Beyond programmable shading[1] 值得去回味和审视。
在DX10 VS、GS和PS都可编程的时候,接下来呢? AMD的Mike Houston画了一张图, 是不是有一点当年SDN的味道?
但是ATI为了复用原来的4D Vector + 1D Scalar的结构,导致后期走向了VLIW,耽误了几年的时间,错失了和nVidia竞争的机会。而Intel 复用X86的核直接导致其独显机会又胎死腹中,都是被自己太成功的车轮碾压到地下..
其中来自Stanford的Kayvon有一个关于< From Shader Code to a Teraflop: How Shader Cores Work >的talk讲的非常精彩。他通过3个Idea描述了心目中的最佳GPU
idea
好处就是可以放下更多的CORE,而且图形学的计算本来并行度就非常高,可以基于Vetex、Primitive及Fragment乃至最后填充的像素级并行都可以做
同时需要注意整个计算任务中,大家还可以共享指令流.
idea
这样对于VS的Vertices、GS的Primitives和PS的Fragments都可以做并行计算了:
紧接着作者就说这里的SIMD不是单纯的指X86 SSE那样的显式向量指令,而是包括一些标量指令,利用硬件向量化,也就是说每个ALU成为一个独立的标量线程,执行一系列指令.
但是SIMD还是有一个问题的,例如在包括分支的功能,效率就低了…如何调度呢?
idea
计算过程中不可避免的需要访存,而GPU本身对延迟是可宽容的,那么如果隐藏延迟就是一个值得考虑的话题了,那么接下来也有了Context的需求
第一个把三颗龙珠凑齐的是nVidia
nVidia Tesla Architecture
这一节只是简单的概述,Tesla开始新的GPGPU架构将会每个架构单独一个章节详细叙述.
针对Unified Processing如何同CPU区分,nVidia更加深刻的意识到了这个问题,Ashu Rege在< An Introduction to Modern GPU Architecture >中明确讲述了通用计算的能力需求,以及如何区分GPU和CPU的算力构成:
-
CPU对延迟敏感,例如对鼠标和键盘的操作,所以CPU最小化延迟,因此带来了其Cache Size加大,同时也伴随着指令预取、乱序执行、和分支计算等大量功能。而GPU对延迟可容忍,只要在两个帧之间能够渲染完就行了,因此并不需要那么大的Cache。
-
CPU基于任务并行,而GPU基于数据并行
最后总结出来就是:
- CPUs are low latency low throughput processors
- GPUs are high latency high throughput processors
或者更直观的说,从计算任务的数据量及并行度来看:
数据规模小 | 数据规模大 | |
---|---|---|
执行并行度高 | A* | GPUs |
执行并行度低 | CPU | NA |
Quiz: 有一个很好玩的问题A*是什么,DPU应该在这个里面如何划分?
正是这一系列的思考,2006年nVidia 革命性的Tesla架构芯片GeForce 8发布了
nVidia注意到Vertex Shader中的Vector ALU在针对一些一些Scaler+Vector混合计算的场景效率过低的问题:
于是开始设计了一个统一的标量核处理架构,这样编译器也更容易处理, 于是它成为第一个完全支持C编程,同时合并了VS和PS并支持GS编程的图形处理器,另一方面每个Thread Processor采用了标量计算的的方式,避免程序员去手工管理Vector寄存器获得更高性能的复杂性。单个处理核心可以在一个时钟周期内执行一次整数或一次浮点指令
而如何将大量的标量处理单元组织起来呢? 以及这些线程该如何调度呢?
它采用了将8个标量计算核(Streaming Processor,SP)和2个特殊函数计算单元(SFU)配合一些Cache和共享内存整合构成一个Streaming Multiprocessor(SM), 然后采用SIMT的方式进行,将32个Thread打包成一个Warp,而一个SM又可以同时管理24个Warp. 然后两个SM共享一个Texture Unit和一个Geometry Controller构成一个Texture/Processing Cluster.
SIMT执行方式类似于SIMD,一条指令可以同时对多个数据处理,但是不同的是,由于每个执行的SM都可以有独立的Branch的能力,所以每个thread编程更加灵活,使得我们可以用通用的C语言代码来描述单个thread的执行。
正是由于新的架构极其灵活的可编程能力,一个名为CUDA(Compute Unified Device Architecture)的编程框架也跟随着G8x一起发布了,它受到了OpenMPI的很多影响,采用Grid、BLock、Thread的方式组织并行计算任务,使得它们和硬件的处理核心完全解耦了,最关键的是它只是给标准的C语言增加了少数几个关键字,大量熟悉MPI的程序员基本上花上两三周的时间就可以完全动手进行CUDA编程。
而第二代Tesla GT200核心发布,支持双精度浮点,更多的线程使得它第一次可以真正的走进HPC的市场了。
而CUDA的内容,伴随着后面Fermi、Kepler、Maxwell、Turing、Volta、Amepere和Hopper等架构,我们把它放到另一个章节再说吧。
ATI 误入VLIW
ATI在被AMD收购后,两个难兄难弟虽然差点破产,但是奇迹般地使这个合并后的图形部门获得了资金,基于TeraScale 1微架构的Radeon HD 2000系列发布,也采用了统一的流处理器引擎。
而执行单元还是4D Vector+1D Scaler的SIMD方式,也为后期在TeraScale2和TeraScale3上偏向VLIW埋下了伏笔, 很多时候只顾着自己硬件设计容易,忽视软件的易用性给它挖了一个大坑。
Intel Larrabee 胎死腹中
它试图利用Pentium P54c这样的5级流水线架构来堆多核,但最终还是胎死腹中
看到Intel的Larrabee的一个Deck,然后脑子里在补把CPU换成Network Processor把GPU换成Switch ASIC,把Larrabee换成Tofino、Silicon One,而如今似乎又来了…真是轮回…结局如何?
结尾
Intel在迷茫后很快的砍掉了Larrabee项目,而后面又产生了一个非常短暂的Xeon Phi产品线,而AMD还在自己的4D+1D上玩5-way VLIW,然后又降到4-way VLIW,并且认为CUDA是nvidia私有生态做不大… 最后在跟编译器搏斗了好久还是放弃了,于2012年发布了Graphics Core Next(GCN)架构.
而nVidia CUDA则在2007~2012的五年间大放异彩. 回头来看这场革命性的变局,ATI和Intel都因为延续过去的一些东西把自己逼向墙角,时到今日,Intel新的Xe架构显卡再次启程,未来如何呢?
另一个感慨是,2008年发布的Cisco QuantumFlow Processor和相应的Cisco Packet Programming(CPP)软件架构,也是完全C的API并行处理的框架,但网络整个工业界过了十多年了,还在C-Like微码或者P4这样类似于2006年的Graphic Shader Language的DSL上打转,有些感慨…
而nVidia在DPU上还在走ARM的路,当然也包括Nitro和国内某家… 回过头再来看这个问题,DPU的架构如何,DPU的CUDA在哪?
Reference
[1]
Beyond programmable shading: https://dl.acm.org/doi/10.1145/1401132.1401145
《GPU架构演化史5 2006-2010 统一着色器带来初代CUDA》来自互联网,仅为收藏学习,如侵权请联系删除。本文URL:http://www.bookhoes.com/692.html