本帖最后由 taizer 于 2012-6-4 02:49 编辑
2.那些年我们追过的CUDA单元 积和熔加运算(fused multiply-add,FMA),是CUDA基本力量之一。CUDA单元具备完整的整数和浮点单元,这种设计为CUDA实现FMA打下了基础。所谓FMA就是将乘法的结果和累加器 A 的值相加,再存入累加器。 比如A=B×C+D 通过FMA此类运算可以单指令完成,而且CUDA还可以将卷积、矩阵、点积等更加复杂的运算拆分成FMA指令在完成运算。 如果从线程分配的角度来看,SM阵列中的CUDA单元在运算时实际被分成4个一组,这种设计至今未变。 关于warp的线程数和CUDA的数量关系,放到后文来说。 G200的主要改动就是每SM8SP,每TPC3个SM,共计10TPC,纹理单元扩充为80个。SM共享缓存扩充为16KB受限于crossba架构,TPC数量增加不易,而采用多SM阵列的方式,也是出于对线程分派器压力的考量。另外G200开始支持64bit的浮点运算,这个依靠多运算单元配合实现的,其实现方式反倒很类似于CPU。 G80之所以被称为超标量,就是因为其SP单元是全功能单元,1D-4D指令皆可以由一个SP独立完成。当然问题也是有的,如果是4D指令,要么消耗4个SP来完成,要么一个SP运行4次来完成。所以还有是效率低下的情况.NVIDIA的应对办法就是采用分频技术,将SP频率提升到2倍于核心频率来运行。这个设计一直被沿用到费米时代,它的缺点就是一致了GPU本身频率的提高。当nvidia试图制造能兼顾科学计算和游戏的庞大核心的时候,往往会遭遇到频率提升问题,更主要的是它甚至影响到了显存控制器的设计。 R600的问题 R600的规格 R600完全的SIMD设计,共计4个阵列,每个阵列16组SP,也就是64组,合计64×5=320个流处理器。每组SP由4个ALU和1个ALU.transcendental单元,于一个仲裁器共同封装。ALU.transcendental也就是全功能单元,在一些文章里称为胖单元。这每组SP只能同时执行一个VLIM5,而VLIM5要依靠UTDP来组合,而每个SIMD阵列所处理的线程列表也是由UTDP来提供,这个列表是完整的,同时列表上的处理类型可以是不同的,这也是它的优势所在。 另外一个部分就是R600的的Z Compression压缩比提升到了16:1,设计目的是为了配合ringbus实现纹理的低占用和提升并发处理能力,双倍的Z-buff压缩也在这一代引入,这种高效的纹理处理优势一直保持到现在,即使后来的设计上双倍压缩并不一直在沿用。 有趣的小设计:细分曲面技术在这一带ATI GPU中就已经有了,但并未引起重视。当时的游戏如果你开启细分曲面,由于API和游戏都没有原生支持,反倒会造成物体的变形,最为典型的就是硬线条的枪管会变的胖胖的。 如果G80不是那么强大,R600也会成为一代经典(从命名就可以看出来,ATI想再现R300的大核心辉煌),当然糟糕的驱动和ROP问题也是存在的。R600的失败直接导致了ATI的芯片策略从R300时期的拼大作强转换到了小芯片策略,这非常成功,甚至近年来NVIDIA也转换到了这种策略。R600性能本身不俗,但问题是它极度缺乏中段产品。2600到2900之间完全是个真空地带,而8600GT到8800ultra之间塞满了8800GS 8800GT 8800GTS。虽然G80的良品率不高,但依靠屏蔽单元的做法,G80的产品线非常丰富,其成本平均下来也不那么高。而8800GT的表现就足够RV600喝一壶的状况搞的AMD很被动。这个问题即使在RV670时代也没有改善。RV670的全额模式也就是3850性能只能和8800GS相较,而3870依旧没有追赶上8800GT,之后NVIDIA的小芯片G94出现后,情况就更糟糕(研发G94是因为黄仁勋认为依靠G92阉割版来应对RV670实在划不来,他希望团队能设计一个小核心产品,改善纹理和ROP效率,以更低的成本来应对RV670)。看看当时3850的降价速度就知道了。也就是说RV670必须有极高的良品率才能在利润上有所斩获。根据当时的官方数据,全额运作的芯片大约在41%左右,而其中有8成可以运行在3870的频率上。反观NVIDIA,依靠冗余晶体管技术,G92能够达到8800GS规格的要远高于RV670,这一上一下成本就低了很多。 AMD的UTDP Ultra Threaded Dispatch Processor(超级线程分派处理器) UTDP作为一个专门的全额的指令调度存在,其包含了全部了指令列表。由于GPU的处理不存在指令中断分支预测,这种顺序架构就对指令的分配和调度提出了极高的设计难度,特别是在处理单元数量暴增的情况下。UTDP将指令分为若干线程分派给各个SIMD矩阵,由于不能够进行中断和乱序,SIMD的仲裁器依靠交替分配来避免由于输出不同处理类型造成的空闲问题。UTDP作为一个总的指令列表,可以根据优先级依靠片上缓存临时跟换相邻的两个线程的执行顺序,如果下一个线程的优先级依旧很高,这个被攒搁的线程会被继续攒搁。而一旦有SIMD阵列空闲,这个线程会被优先发送,而UTDP仅有512K的缓存,一直都不够用。 在转换架构之后,这单元实际已经没有用了,但依旧被保留下来了,我后面会说为什么。 VLIW5的设计思路及相关问题 每个SIMD单元内含1大4小5个ALU,一个仲裁单元和一个分支执行单元。其中那个大的ALU可以执行全部的SIMD指令,剩余四个必须和“大家伙”配合才能执行。通常都是通过指令分配单元进行组合后分配给SIMD矩阵。每个SIMD矩阵同一时间执行一个线程,分配给其内部的SIMD单元。最完美的情况下所有指令都被组合成5个一组分配给SIMD单元,实际的情况是,由于+vliw的先天缺陷,在指令序列器中只能尽量做到分配和组合成这种并行指令,加之每个矩阵的线程处理是同一类型,后面的数据要等待前面的处理完成,这种分配和组合根本无法做到100%满足SIMD单元。比如如果出现大量IN、COS、MULHI、MULLO、RECIP、SQRT ,ALU.transcendental不得不看着ALU闲着而自己来独立执行这些指令。而且由于实际的指令环境下很难找到4D+1D的完美组合,很多时候ALU.transcendental和ALU虽然双发,但ALU.transcendental只是在补完指令,并不起实际作用。也就是说虽然可以组合1D-4D的所有指令来处理,但所有流处理器不能同时工作么,比如在RV770的800个SP,任何指令情况下都不能全部启动。这个是由于它的指令表来自一个完整的指令序列表,必须按照类型顺序发送各种类型指令。在VLIW4后改进了这一情况。直到GCN架构,依靠分级的指令分发实现了MIMD的指令分发SIMD的指令处理架构,真正实现了流处理器的全额运作。当然Tahiti也有他的问题,由于SP数量的暴力堆叠,指令列表的压力已经非常大了,这个问题在Cayman 上也就出现了。其直接的表现就是单流处理器效率相较RV770时代没有提升。这个设计思路也并不是AMD没有看到这个问题,而在于SP的晶体管耗用度相对很低,而且采用暴力堆叠的方式可以快速的推出性能更高的新品占领市场。这个问题也同时出现在了采用超标量架构的NVIDIA GPU上。 从这个角度来说,超长指令架构对驱动的依赖也非常大。 也正是因为这种设计,RV770在服务器的应用中更多的时候是作为向量节点。 在RV770阶段,AMD已经为其每个SIMD阵列引入了 16KB Local Data Share,这东西的作用更主要的还是让其内部的VLIW5 内核共享线程数据,在过去只能依靠UTDP和显存取数,这也为后来AMD走向通用计算奠定了一定的基础。 RV600的RINGBUS结构 字面意思,环路。RV600的TPC和外总线之间,ROP和内存控制器之间,全是环路所以又叫双环路。RV770之后,TPC这一级的环路就取消了。双环路的优势在于,一个64bit的显存控制器,他采用的组合是32×2而不是64×1,形成更多的节点,配合内环路,如果不考虑高分辨材质的影响这种结构的延迟性能应该接近于512bit。可惜的是RV600仅有16个ROP还出了毛病,这个双环路只带来了高发热高晶体管耗用。
从GF100开始的新技术: Tesselation(曲面细分) 曲面细分的基本解释就是,利用显卡的单元在原本的建模基础上,对三角形进行进一步的分割,从而实现更平滑的建模精度。 目前的游戏引擎主要依靠纹理和光照来实现较高的视觉,而建模的精度提升相对于其他要素则要缓慢的多,其原因在于过多的顶点会给处理器带来较高压力。 前面也提到曲面细分是原本就有的技术,直到DX11时代才真正被作为一项主要的画面改进技术,如果使用得当,应该不亚于全屏抗锯齿的意义。 在GF100中,NVIDIA为每一个GPC配置了一个Raster引擎,每个SM配置一个PolyMorph引擎,这2个单元就具体负责细分曲面技术。
PolyMorph引擎
顶点拾取 曲面细分 视图接口转换 属性设置 流输出 在这5个步骤的进行过程中,每一个步骤的结果都交由PolyMorph引擎所在的SM阵列进行处理,处理后的结果交由下一个步骤,5个步骤完成后,细分曲面中的三角形分割也就基本完成,这个结果将被发送至所在GPC的Raster引擎。
Raster引擎
即光栅引擎,在之前的GPU中,Raster所实现的功能是由其他单元实现的,其数量也仅有一个。包括PolyMorph的功能实际也是和现在Raster整合在一起,现在为了满足细分曲面的需要而进行重新的分割和组合,其位置也从前端进入到GPC和SM阵列,当然数量的提升也非常大。这是GF100曲面细分性能强大的关键因素。由于从本质上来说这并非是全新的模块,所以AMD就采取对原单元增加Tesselation步骤,然后分割设计的方式实现了对曲面细分功能的支持。 现在的游戏对曲面细分的支持还不够广泛,未来如何做到广泛应用不而是滥用影响到性能也是个问题。
GPC
GPC的设计特点:由于PolyMorph和Raster的进驻,而且纹理拾取和纹理过滤合并成一并入SM阵列,GPC在实际上已经可以独立完成一个GPU所要完成的所有工作,外围只要加上ROP和显存控制器就可以了。 全新设计的GigaThread引擎 由于GF100的MIMD特性较为彻底,GigaThread设计被用来满足多线程的应用。GigaThread有点类似超级线程分派器,主机接口把指令传送到GigaThread之后,GigaThread负责从内存向显存拷贝数据,之后GigaThread要把需要SM处理的数据创建成线程模块,然后分配给SM阵列,GigaThread还可以根据负责调整线程的优先度。 SM内部的设计变化: GF100的SM阵列内含2个32粒子的线程调度器(Wrap调度器),且Wrap调度器之间无关联性,所以2个Wrap调度器可以同时执行,形成双发。每个Warp调度器下辖2个分派单元,同时SM阵列内含16个LD/ST单元,LD/ST将具体分配线程的去向。这些外围和SM阵列内的各级片上存储共同构成了SM阵列的线程和指令分配。(如果Wrap满载,则每个周期会有一个CUDA单元空载,此时寄存器满载。如果CUDA单元无空载,则Warp会出现部分空载,寄存器或者满载或者出现空载。从道理上来说是CUDA满载最好,但实际情况是Warp和寄存器都满载的时候利用效率最高,但同时处理的指令数量又是最少。很纠结吧- -!) 纹理单元的设计: 纹理单元的位置由原来的GPU变动到了SM阵列,使得其的频率脱离了核心频率的束缚,不过仍无法和CUDA同频。另外纹理拾取和纹理定址依旧采用分割设计,达到了4:1的比率。更主要的是,SM阵列和纹理单元的交互更加直接,之前纹理拾取和纹理定址的高速缓存也内置在了SM阵列中。 片上缓存的设计不再赘述,理解成主要是分级设计就可以了,关键叙述起来篇幅太大,码字很累的。 线程关联性软着陆 在GK104的SMX阵列中,内涵高达192个SP单元,这个数量直接达到了GTS450所拥有的SP单元总数。这是一种SIMD的设计方向,在这样规模的SP数量下,必然会出现线程关联性的分割问题,也就是在AMD早期的GPU设计中会出现的问题。为了解决SIMD设计方向上的缺陷,GK104将线程关联性的分割交给了CPU来完成,而不是依靠线程分派器。所以在底层测试中GK104显示出了对CPU的较高依赖性,只是这种依赖性在游戏中的表现还不明显。根据目前的情况来看,NVIDIA下一步的设计思路及有可能是在GPU内部设计一个全新的RISC架构的协处理器,用以分担线程关联性分割的任务。
所谓执行 Thread SP所执行的最基本单元,也就是线程,在实际中就是像素的定义。 CTA 多个thread合起来就是CTA(线程块),Warp执行的就是这个东西。 Block 就是打包分配前的thread。由CTA组合而成。 Grid 在一个SM 阵列中可以同时执行多个Block,当全部Block中的CTA都被执行完成后,就进入了下一个循环。而这个循环中所有的Block合起来就称为Grid。 GK104那些变化 我在写这个东西之前并没有在意到这个变化,算写的过程中的收获吧。 GF100/110的SM数据 32CUDA、2个Wrap、4个指令分派、16个LD/ST、4个SPU、1个PolyMorph、4个纹理、64KB片上快取 GK104 192个CUDA、4个Wrap、8个指令分派、32个LD/ST、32个SPU、1个PolyMorph、16个纹理、64KB可分配片上快取 CUDA核心负责像素、顶点、几何着色、物理计算等处理,指令分配单元负责线程群组的调度以及指令发射,载入与存储单元负责为线程计算源地址和目标地址,特殊功能单元负责执行抽象的指令,比如正弦、余弦、倒数和平方根,还有图形插值指令,PolyMorph 2.0引擎单元负责顶点拾取、曲面细分、视口转换、属性设定以及流输出等功能,纹理单元则负责纹理过滤、纹理采样、计算纹理地址并将数据输出至显存,而共享存储器和一级缓存是互补的作用,能够广泛地重复利用片上数据而减少片外通信量,从而提高工作效率。 责纹理过滤、纹理采样、计算纹理地址并将数据输出至显存,而共享存储器和一级缓存是互补的作用,能够广泛地重复利用片上数据而减少片外通信量,从而提高工作效率。 G80时代随着统一着色器架构的到来而出现,成为继核心频率、显存频率之外的另外一个性能指标,后来一直延续到Fermi架构(近两年一般为核心频率的两倍,GK104回归同频)。 纹理单元数量的扩充是因为阵列数量的改变所以单SMX拥有了更多纹理,但其他单元的数量改变确有蹊跷之处。以下的分析只是个人的推测,因为官方白皮书真正涉及到的有效的东西并不多。 CUDA的数量扩容了6倍之多,指令分派器确和LD/ST确只扩容了2倍。一方面由于SPU单元数量的增加,一些特殊的运算可能就直接交由SPU来完成。另一个方面,我们来看。SMX的Wrap的实际thread数量仅有128个,这个数量和192个CUDA单元明显的不对应。 这得从上面的所谓执行来说(或者胡扯) 在执行 CUDA 程序的时候,每个SP对应一个 thread。每个 SM 则对应一个 block。每一个Warp对应2个指令分派器,每个指令分派器对应16个thread。如果我们把每4个CUDA看成一组,这其中有一个SP进行预读取或者等在一个FMA结果,那么每4个一组的CUDA一次4D循环运算会产生16个结果。这些预读取不能依靠片上缓存来执行因为这个量太大,而是同时直接消耗掉一个thread的执行来完成。这种情况下,GK104的Warp就会出现空载,而寄存器会接近满载。如果出现每4个CUDA,其中3个执行FMA运算,而另一个CUDA单元不需要预读取,则刚好用到8个指令分派器总共128thread,此时wrap满载。32个LD/ST也是刚好对应Warp空载时候的设计。这也就是前文说过的CUDA满载最好,但实际情况是Warp和寄存器都满载的时候利用效率最高,但同时处理的指令数量又是最少。从某种意义上来说,GK104满载执行时看作每SMX192SP,而执行最多指令时看作每SMX128SP。 从演变上看,G80冗余,GF100半冗余,而GK104刚刚够。 GCN架构中的可以说说的东西 其实由于AMD转换到MIMD阵营,我本来不打算说GCN了,毕竟共性很大,而且码字又很累,是吧?但有个设计比较前瞻化,虽然NVIDIA也有这种设计,但AMD的意图更加明显。 ACE 全称Asynchronous Compute Engine,译为异步计算引擎。 ACE位于整个GPU的最前端管理任务队列,它会将线程块规整的分发给后面的ALU团簇。ACE是所有GPU任务的起点,它的存在和表现直接关系到了GPU进行图形及通用计算任务是的效率表现。这个玩意就是干线程分派这个活的,目前和UTDP处于共存状态。ACE和NVIDIA的前端线程管理模块的区别在于ACE还负责几何部分。原本的GDS被放置在了每个CU中,而且这个容量达到了32K,何其爽也~ 那我这里为什么要把ACE提溜出来说。ACE在其设计上已经有了半拉协处理的样子,AMD实际上不仅仅在转换到MIMD,也在为下一个大的战役打下技术前奏。UTDP的保留正是为了和ACE在未来实现融合。由这里引出下一小节,也是最后一小节,也是最短的一小节:芯片策略。 第三节:芯片策略 2005年K8发售,2006年7月收购ATI,2011年1季度发布推土机,4季度发布南方群岛。而在这期间AMD依靠对K8的修补和工艺进步苦撑到现在,GPU部分则也是依靠对SIMD的架构不断修改。直到2011年AMD的CPU和GPU都迎来了架构的巨大变动,似乎是AMD多年磨一剑的爆发,但事实是无论是推土机还是南方诸岛其性能相对于竞争对手已经落后。AMD在干什么?为什么这2个新品的宣传费用还赶不上APU产品?这些年他的工程师团队在补番还是怎么了? (补遗:GCN的ALU在媒体上被只是被简单标注为1D单元,如果单从数量上看较GK104有很大优势,而且位宽也高出不少,为什么性能如此接近。实际上GCN的ALU设计依旧没有完全脱离原本架构,ALU.transcendental被移除,原本的ALU进化成向量处理器,但仍旧不是完整的整/浮运算器,部分浮点运算和函数要依靠SPU来完成。其二,ALU无法独立执行全部的标量运算,部分可独立执行,部分需要多个ALU合作。而且由于实际上还是向量处理器,所以部分标量运算时对向量寄存器依赖较大) 实际上AMD在下一盘和大的棋,他的技术革命应该还有1-2代,这一代的产品依旧是保证存活而已。 目前APU只是把CPU和GPU做到了一个芯片里,就异步计算的角度来说甚至还不如intel的核心显卡,人家好歹能共享下L3.APU里的CPU的运算结果不能直接给GPU调用,反过来也一样,放眼望去只是一个性价比产品而已。 让我们再回头看看推土机。AMD没有去设计超线程技术,而是将处理器模块化实现多线程。实际上这种设计已经出现了SIMD的影子,而且这个架构很容易过渡到MIPS,没错那个隶属于RISC的MIPS。 AMD下一步的打算应该是合并GPU和CPU这个他喊了很久很久的融合,合并的还有工程师团队。在未来的AMD产品里将只剩下APU这一款产品,而且将分为CISC和RISC两大系列。移动手持设备的蛋糕现在还很大,必然要做的。ACE和UTDP的设计经验将很容易帮助AMD进行这种合并的过渡。 NVIDIA的小芯片战主流,大芯片走计算和发烧已成定局。当然这个2006年就收购X86团队的人向来野心不小。也许不用太迟,我们就能看到携带RISC协处理器的NVIDIA显示芯片,而这种设计思路则源自移动平台的耕耘。 在这一点上,AMD和NVIDIA到是殊途同归。 结语:耗时多天的3D王朝总算完成,我也了解了一桩事情,下一篇应该是关于CPU的,但根据我的尿性估计写完得一年多吧······ 作为PC的终端用户,我们的目的是希望产品越来越好越来越便宜,这一点上我们是相同的目的。而芯片厂商则希望产品利润更高销量更好。所以完全没有必要为了所谓的阵营吵来吵去。 在北海公园的长椅上,坐着两个中年男人,水面上倒影着夕阳的余辉。 坐在左边的这一位叫何国源,他悄悄的拉起右边这位中年男子的手,轻声的说道:我说仁勋啊,要不咱俩就在一起吧? 右边的这位男子娇嗔道:轮家才不要跟你在一起呢~ 我这个人行文向来毫无节操,写这么一篇东西差点没憋坏洒家,写道这里才找回感觉。
|