圖形與計(jì)算那些事 AMD次世代架構(gòu)解析
泡泡網(wǎng)顯卡頻道1月6日 作為顯卡來說,AMD的Radeon自HD4000時(shí)代以來為游戲玩家提供了眾多優(yōu)秀的產(chǎn)品,HD5000/HD6000系列絲毫不輸給NVIDIA同級(jí)產(chǎn)品,性能、功能、價(jià)格、功耗等各方面表現(xiàn)得都很不錯(cuò)。對(duì)于AMD下代HD7000系列,我們毫不懷疑它在3D游戲中會(huì)有更出色的表現(xiàn)。
但作為GPU來說,AMD的產(chǎn)品顯然要遜色很多,不支持物理加速、Stream通用計(jì)算性能不如CUDA,支持GPU加速的軟件也屈指可數(shù),這已經(jīng)成為AMD最大的軟肋,并且成了NVIDIA和NFan們攻擊的對(duì)象。
隨著時(shí)間的推移,保守的AMD終于嘗到了固步自封的苦果:當(dāng)NVIDIA的CUDA計(jì)算課程進(jìn)入高校學(xué)堂、Tesla殺進(jìn)超級(jí)計(jì)算市場、Quadro拿下95%的專業(yè)卡市場份額之時(shí),AMD的Radeon還只能游弋在3D游戲領(lǐng)域,苦守來之不易的半壁江山。
想當(dāng)年AMD率先提出GPU通用計(jì)算的概念,但最終卻在NVIDIA的CUDA手中發(fā)揚(yáng)光大。很多人以為這是AMD收購ATI后自顧不暇的關(guān)系,其實(shí)根本原因還在于GPU的架構(gòu)——傳統(tǒng)基于3D圖形處理的GPU不適合于進(jìn)行大規(guī)模并行計(jì)算,AMD的GPU擁有恐怖的理論運(yùn)算能力卻無從釋放。而NVIDIA則從G80時(shí)代完成了華麗的轉(zhuǎn)身,逐步完善了硬件和軟件的協(xié)同工作,使得GPU成為高性能計(jì)算必不可少的配件。
俗話說的好:苦海無涯、回頭是岸,亡羊補(bǔ)牢、為時(shí)不晚。AMD終于在代號(hào)為Southern Islands(南方群島)的新一代GPU中,啟用的全新的架構(gòu),AMD稱之為“Graphics Core Next”(GCN,次世代圖形核心),并冠以革命性的稱號(hào)。這是AMD收購ATI之后的近5年來第一次對(duì)GPU架構(gòu)進(jìn)行“傷筋動(dòng)骨”的“手術(shù)”,而架構(gòu)調(diào)整的核心內(nèi)容則是為并行計(jì)算優(yōu)化設(shè)計(jì)。
那AMD的“次世代圖形核心”相比沿用了五年之久的架構(gòu)到底有何改進(jìn)?其并行計(jì)算性能相比對(duì)手NVIDIA有無優(yōu)勢?3D游戲性能會(huì)否受到影響呢?本文將為大家做一個(gè)全方位的解析,文中會(huì)穿插一些3D渲染原理以及顯卡基礎(chǔ)知識(shí),并談?wù)凣PU圖形與計(jì)算的那些事兒……
微軟的DirectX 9.0C是一個(gè)神奇的圖形API,自2004年首款DX9C顯卡GeForce 6800 Ultra問世以來,至今已有將近8年時(shí)間,之后雖然微軟發(fā)布了DX10、DX10.1、DX11、還有現(xiàn)在的DX11.1等多個(gè)新版本,但DX9C游戲依然是絕對(duì)主流,DX10以后的游戲全部加起來也不過幾十款而已!
因此,當(dāng)年的DX9C顯卡之戰(zhàn),很大程度上決定了此后很多年的顯卡研發(fā)策略。從最開始X800不支持DX9C對(duì)抗6800失利,到X1800支持DX9C卻性能不濟(jì),再到X1900登上頂峰,還有半路殺出來XBOX360這個(gè)程咬金,ATI被AMD收購前的經(jīng)歷猶如過山車般驚險(xiǎn)刺激!
DXC如此長壽的原因,相信游戲玩家們已經(jīng)猜到了,那就是游戲主機(jī)太長壽了——微軟XBOX360以及后來索尼PS3使用的GPU都是DX9C時(shí)代的產(chǎn)品。游戲開發(fā)商的主要盈利來源在主機(jī)平臺(tái),所以根本沒心思把PC游戲做好,尤其對(duì)提高PC游戲的畫面及引擎優(yōu)化提不起興趣,個(gè)別以高畫質(zhì)而著稱的PC游戲倍受打擊,很多DX10游戲續(xù)作倒退到DX9C就是很好的證明。
可以說,這么多年來PC 3D游戲圖形產(chǎn)業(yè)的發(fā)展,成也微軟、敗也微軟。
XBOX360的GPU——Xenos,由ATI設(shè)計(jì)
Xenos的核心架構(gòu)圖
微軟XBOX360的成功,給GPU供應(yīng)商ATI發(fā)出了一個(gè)信號(hào),那就是今后N年內(nèi)的游戲都將基于XBOX360的硬件而開發(fā)。當(dāng)時(shí)ATI與Xenos同時(shí)研發(fā)的一顆GPU代號(hào)為R580,倆者擁有相似的架構(gòu),而R580在當(dāng)年也成為DX9C顯卡的王者,這就讓ATI更加堅(jiān)定了維持現(xiàn)有架構(gòu)不變的決心。
下面我們就來看看R580的核心架構(gòu),也就是當(dāng)年的王者X1900XTX/X1950XTX所使用的GPU,后來次高端RV570核心(X1950Pro)的架構(gòu)也類似。
R580:8個(gè)頂點(diǎn)著色單元、48個(gè)像素著色單元、16個(gè)紋理單元
DX9C顯卡還沒有統(tǒng)一渲染架構(gòu)的概念(XBOX360的Xenos是個(gè)特例),所以R580依然是頂點(diǎn)與像素分離式的設(shè)計(jì)。當(dāng)時(shí)的GPU核心部分被稱為管線,比如7800GTX擁有24條像素渲染管線,但X1900XTX卻不能稱為擁有48條像素渲染管線,因?yàn)樗南袼嘏c紋理單元數(shù)量不對(duì)等。
GPU的工作原理:
顯卡的渲染流程是通過頂點(diǎn)單元構(gòu)建模型骨架,紋理單元處理紋理貼圖,像素單元處理光影特效,光柵單元負(fù)責(zé)最終的像素輸出。
GPU的管線是什么:
在R580之前,GPU的像素單元與紋理單元還有光柵單元是綁定在一起的,數(shù)量一樣多,整個(gè)渲染過程就是流水線作業(yè),因此像素與紋理加起來稱為一條管線。
什么是3:1架構(gòu)?
R520核心(X1800XT)的像素與紋理都是16個(gè),但R580核心在紋理單元維持16個(gè)不變的情況下,把像素單元擴(kuò)充了3倍達(dá)到了48個(gè)之多。ATI研發(fā)工程師發(fā)現(xiàn)新一代游戲中使用像素著色單元的頻率越來越高,各種光影特效(尤其HDR)吃掉了像素著色單元的所有資源,而紋理單元的負(fù)載并不高,繼續(xù)維持像素與紋理1:1的設(shè)計(jì)就是浪費(fèi)資源,于是ATI根據(jù)3D游戲引擎的發(fā)展趨勢做出了改變,并把R580這種不對(duì)等的架構(gòu)稱之為3:1黃金架構(gòu),管線的概念至此消失。
像素(算數(shù))與紋理的比例逐年提高
當(dāng)年ATI前瞻性的架構(gòu)在部分新游戲中得到了應(yīng)驗(yàn),比如在優(yōu)品飛車10、細(xì)胞分裂4、上古卷軸4等游戲中X1900XTX的性能遠(yuǎn)勝7900GTX。此外ATI專為HDR+AA優(yōu)化的架構(gòu)與驅(qū)動(dòng)也讓ATI風(fēng)光無限。
但事實(shí)上,從1:1大躍進(jìn)到3:1有點(diǎn)太激進(jìn)了,在包括新游戲在內(nèi)的絕大多數(shù)主流游戲中,都無法充分利用多達(dá)48個(gè)像素著色單元的能力。于是ATI的工程師們又有了新的想法:何不用這些像素單元來做一些非圖形渲染的計(jì)算呢?像素單元的核心其實(shí)就是ALU(算術(shù)邏輯單元),擁有十分可觀的浮點(diǎn)運(yùn)算能力。
蛋白質(zhì)折疊分布式計(jì)算開啟GPU計(jì)算大門:
2006年9月,在X1900XTX發(fā)布半年之后,ATI與斯坦福大學(xué)相關(guān)科研人員合作,開發(fā)了首款使用GPU浮點(diǎn)運(yùn)算能力做非圖形渲染的軟件——Folding @ Home第一代GPU運(yùn)算客戶端。
Folding@home是一個(gè)研究蛋白質(zhì)折疊、誤折、聚合及由此引起的相關(guān)疾病的分布式計(jì)算工程。最開始F@H僅支持CPU,后來加入了對(duì)PS3游戲機(jī)的支持,但同樣是使用內(nèi)置的CELL處理器做運(yùn)算。F@H因ATI的加入為GPU計(jì)算翻開了新的一頁,當(dāng)然F@H加入了對(duì)NVIDIA DX10 GPU的支持那是后話。
什么是通用計(jì)算?
當(dāng)時(shí)的GPU計(jì)算被稱為GPGPU(General Purpose GPU),傳統(tǒng)的圖形處理器可以被用來做通用目的計(jì)算項(xiàng)目。所謂通用計(jì)算的大體流程就是:待處理的數(shù)據(jù)—〉轉(zhuǎn)換成圖形數(shù)據(jù)—〉GPU處理—〉處理后的圖形數(shù)據(jù)—〉轉(zhuǎn)換成所需數(shù)據(jù)。其實(shí)通用計(jì)算就是把數(shù)據(jù)轉(zhuǎn)換為GPU能夠“看懂”的圖形數(shù)據(jù),實(shí)際上是作為虛擬硬件層與GPU通訊,由于需要前后兩次編譯的過程,因此想要利用GPU強(qiáng)大的浮點(diǎn)運(yùn)算能力,需要很強(qiáng)大的編譯器,程序員的開發(fā)難度可想而知,CPU的運(yùn)算量也比較大。
除了蛋白質(zhì)折疊分布式計(jì)算外,當(dāng)年ATI還開發(fā)了AVIVO Video Converter這款使用GPU加速視頻轉(zhuǎn)碼的小工具,雖然效果一般,但也算是開了個(gè)好頭。
雖然GPU通用計(jì)算的實(shí)現(xiàn)難度很大,但至少GPU實(shí)現(xiàn)了非圖形計(jì)算的目的,而且其性能確實(shí)要比當(dāng)時(shí)的CPU快十幾倍。小有所成的ATI被勝利沖昏了頭腦,他們認(rèn)為自己研發(fā)出了非常先進(jìn)的、最有前瞻性的GPU架構(gòu),還找到了讓GPU進(jìn)行通用計(jì)算的捷徑、還有了AMD這座靠山……最終促使AMD-ATI做出了保守的決定——下代GPU繼續(xù)沿用R580的架構(gòu),不做深層次的改動(dòng)。
R520->R580的成功,多達(dá)48個(gè)著色單元功不可沒,這讓ATI對(duì)龐大的ALU運(yùn)算單元深信不疑。ATI認(rèn)為只要繼續(xù)擴(kuò)充著色單元,就能滿足新一代DX10及Shader Model 3.0的要求。
著色單元的結(jié)構(gòu):
在圖形處理中,最常見的像素都是由RGB(紅黃藍(lán))三種顏色構(gòu)成的,加上它們共有的信息說明(Alpha),總共是4個(gè)通道。而頂點(diǎn)數(shù)據(jù)一般是由XYZW四個(gè)坐標(biāo)構(gòu)成,這樣也是4個(gè)通道。在3D圖形進(jìn)行渲染時(shí),其實(shí)就是改變RGBA四個(gè)通道或者XYZW四個(gè)坐標(biāo)的數(shù)值。為了一次性處理1個(gè)完整的像素渲染或幾何轉(zhuǎn)換,GPU的像素著色單元和頂點(diǎn)著色單元從一開始就被設(shè)計(jì)成為同時(shí)具備4次運(yùn)算能力的運(yùn)算器(ALU)。
數(shù)據(jù)的基本單元是Scalar(標(biāo)量),就是指一個(gè)單獨(dú)的值,GPU的ALU進(jìn)行一次這種變量操作,被稱做1D標(biāo)量。由于傳統(tǒng)GPU的ALU在一個(gè)時(shí)鐘周期可以同時(shí)執(zhí)行4次這樣的并行運(yùn)算,所以ALU的操作被稱做4D Vector(矢量)操作。一個(gè)矢量就是N個(gè)標(biāo)量,一般來說絕大多數(shù)圖形指令中N=4。所以,GPU的ALU指令發(fā)射端只有一個(gè),但卻可以同時(shí)運(yùn)算4個(gè)通道的數(shù)據(jù),這就是SIMD(Single Instruction Multiple Data,單指令多數(shù)據(jù)流)架構(gòu)。
R580的Shader單元結(jié)構(gòu)
顯然,SIMD架構(gòu)能夠有效提升GPU的矢量處理性能,由于VS和PS的絕大部分運(yùn)算都是4D Vector,它只需要一個(gè)指令端口就能在單周期內(nèi)完成4倍運(yùn)算量,效率達(dá)到100%。但是4D SIMD架構(gòu)一旦遇到1D標(biāo)量指令時(shí),效率就會(huì)下降到原來的1/4,3/4的模塊被完全浪費(fèi)。為了緩解這個(gè)問題,ATI和NVIDIA在進(jìn)入DX9時(shí)代后相繼采用混合型設(shè)計(jì),比如R300就采用了3D+1D的架構(gòu),允許Co-issue操作(矢量指令和標(biāo)量指令可以并行執(zhí)行),NV40以后的GPU支持2D+2D和3D+1D兩種模式,雖然很大程度上緩解了標(biāo)量指令執(zhí)行效率低下的問題,但依然無法最大限度的發(fā)揮ALU運(yùn)算能力,尤其是一旦遇上分支預(yù)測的情況,SIMD在矢量處理方面高效能的優(yōu)勢將會(huì)被損失殆盡。
DX10時(shí)代,混合型指令以及分支預(yù)測的情況更加頻繁,傳統(tǒng)的Shader結(jié)構(gòu)必須做相應(yīng)的改進(jìn)以適應(yīng)需求。NVIDIA的做法是將4D ALU全部打散,使用了MIMD(Multi Instruction Multiple Data,多指令多數(shù)據(jù)流),而AMD則繼續(xù)沿用SIMD架構(gòu),但對(duì)Shader微架構(gòu)進(jìn)行了調(diào)整,稱為超標(biāo)量架構(gòu)。
R600的5D超標(biāo)量流處理器架構(gòu):
作為ATI的首款DX10 GPU,架構(gòu)上還是有不少改進(jìn)的,DX10統(tǒng)一渲染架構(gòu)的引入,讓傳統(tǒng)的像素渲染單元和頂點(diǎn)渲染單元合二為一,統(tǒng)稱為流處理器。R600總共擁有64個(gè)Shader單元,每個(gè)Shader內(nèi)部有5個(gè)ALU,這樣總計(jì)就是320個(gè)流處理器。
R600的Shader單元結(jié)構(gòu)
R600的Shader有了很大幅度的改進(jìn),總共擁有5個(gè)ALU和1個(gè)分支執(zhí)行單元,這個(gè)5個(gè)ALU都可以執(zhí)行加法和乘加指令,其中1個(gè)"胖"的ALU除了乘加外之外還能夠進(jìn)行一些函數(shù)(SIN、COS、LOG、EXP等)運(yùn)算,在特殊條件下提高運(yùn)算效率!
與R580不同的是,R600的ALU可以在動(dòng)態(tài)流控制的支配下自由的處理任何組合形式的指令,諸如1+1+1+1+1、2+2+1、2+3、4+1等組合形式。所以AMD將R600的Shader架構(gòu)稱作Superscalar(超標(biāo)量),完美支持Co-issue(矢量指令和標(biāo)量指令并行執(zhí)行)。
R600超長指令集的弊端:
從Shader內(nèi)部結(jié)構(gòu)來看,R600的確是超標(biāo)量體系,但如果從整個(gè)GPU宏觀角度來看,R600依然是SIMD(單指令多數(shù)據(jù)流)的VLIW(超長指令集)體系:5個(gè)ALU被捆綁在一個(gè)SIMD Shader單元內(nèi)部,所有的ALU共用一個(gè)指令發(fā)射端口,這就意味著Shader必須獲得完整的5D指令包,才能讓內(nèi)部5個(gè)ALU同時(shí)運(yùn)行,一旦獲得的數(shù)據(jù)包少于5條指令,或者存在條件指令,那么R600的執(zhí)行效率就會(huì)大打折扣。
例如:指令一:a=b+c;指令二:d=a*e。這兩條指令中,第二條指令中的a必須等待第一條指令的運(yùn)算結(jié)果,出現(xiàn)這樣的情況時(shí)候,兩條指令大多數(shù)情況下就不能實(shí)現(xiàn)超標(biāo)量執(zhí)行了。
顯然,想要完整發(fā)揮R600的性能必須滿足苛刻的條件,這個(gè)條件不僅對(duì)驅(qū)動(dòng)和編譯器提出了額外的要求,而且要求程序必須讓條件指令不存在任何關(guān)聯(lián)性,難度可想而知。最終結(jié)果就是絕大多數(shù)情況下R600都無法發(fā)揮出的理論性能,而且其執(zhí)行效率會(huì)因?yàn)閺?fù)雜指令的增多而不斷下降。
HD2900XT的失敗來自于很多方面,GPU核心架構(gòu)只是冰山一角,就算保守的AMD沿用了DX9C時(shí)代的老架構(gòu),性能也不至于如此不濟(jì)。但無奈GPU架構(gòu)已經(jīng)定型,短期內(nèi)是無法改變了,HD2000和HD3000一敗涂地,AMD咬牙硬抗了兩年之久。就在大家為R600的架構(gòu)爭論不休,大談VLIW指令集的弊端有多么嚴(yán)重時(shí),AMD終于迎來了翻身之作——RV770核心。
RV770核心:暴力擴(kuò)充流處理器
RV770相比R600/RV670,核心部分依然沒有任何變化,沿用了之前的Shader單元設(shè)計(jì),只是將數(shù)量擴(kuò)充了2.5倍,流處理器達(dá)到了800個(gè)之多!
RV670/R600是4組SIMD,每組16個(gè)Shader,每個(gè)Shader 5個(gè)流處理器;RV770是10組SIMD,每組16個(gè)Shader,每個(gè)Shader 5個(gè)流處理器。流處理器部分直接擴(kuò)充了2.5倍!
雖然對(duì)流處理器部分沒有改動(dòng),但AMD對(duì)流處理器以外的幾乎所有模塊都進(jìn)行了改進(jìn),從而使得性能和效率有了質(zhì)的提升,具體改動(dòng)如下:
抗鋸齒算法改變,性能大幅提升
紋理單元和光柵單元部分,和流處理器一樣都是數(shù)量翻了2.5倍,但值得一提的是,抗鋸齒算法已經(jīng)由R600/RV670的流處理器部分轉(zhuǎn)移至光柵單元部分,因此RV770的AA效率大幅提高,一舉超越了N卡重現(xiàn)X1000時(shí)代的輝煌,這也就是RV770表現(xiàn)令人驚異的主要原因。
在紋理單元與顯存控制器之間設(shè)有一級(jí)緩存,RV770核心相比RV670,L1 TC容量翻倍,再加上數(shù)量同比增加2.5倍,因此RV770的總L1容量達(dá)到了RV670/R600的五倍之多!
放棄環(huán)形顯存總線,改用交叉總線
RV770還放棄了使用多年的環(huán)形顯存總線,估計(jì)是因?yàn)楦哳l率下數(shù)據(jù)存取命中率的問題,回歸了交叉總線設(shè)計(jì),有效提高了顯存利用率,并節(jié)約了顯存帶寬。還有GDDR5顯存的首次使用,瞬間將顯存位寬翻倍,256Bit GDDR5的帶寬達(dá)到了當(dāng)時(shí)N卡512Bit GDDR3的水平。
總的來說,雖然流處理器部分沒有做改動(dòng),但RV770的非核心架構(gòu)部分有了很大的改良,上代產(chǎn)品許多設(shè)計(jì)失誤得到了糾正,在流處理器數(shù)量暴增運(yùn)算能力大大加強(qiáng)的情況下,消除了功能模塊的瓶頸,從而使得性能有了大幅改進(jìn)。
VLIW并未降低3D效率,只是妨礙了GPU計(jì)算
HD4870/HD4850打了一場漂亮的翻身仗,也讓唱衰VLIW的人看傻了眼,之前大家普遍認(rèn)為R600/RV670失敗的主要原因是VLIW的低下效率,事實(shí)證明VLIW并沒有錯(cuò),其效率問題并沒有嚴(yán)重到失控的地步,畢竟DX9C游戲還是主流,頂點(diǎn)與像素操作指令還是大頭。AMD只是錯(cuò)誤的判斷了抗鋸齒的算法和效率,導(dǎo)致第一代DX10 GPU性能不如預(yù)期。
但最關(guān)鍵的問題不在3D游戲性能方面,AMD對(duì)GPU并行計(jì)算依然沒有投入足夠多的重視,AMD一方面在鼓吹自家Stream通用計(jì)算并不輸給CUDA,各種商業(yè)軟件未來將會(huì)加入支持,另一方面GPU架構(gòu)未做任何調(diào)整,API編程接口支持也舉步維艱。結(jié)果就是Stream軟件無論數(shù)量、質(zhì)量、性能還是發(fā)布時(shí)間都要遠(yuǎn)遠(yuǎn)落后于CUDA軟件。
R600的失敗讓AMD明白了一個(gè)道理:從哪跌倒要從哪爬起來;RV770的成功讓AMD堅(jiān)信:我們的架構(gòu)是沒有問題的,以前的失敗只是一個(gè)小小的失誤,R600的架構(gòu)前途無量,應(yīng)該加快腳步往前沖……于是乎RV870誕生了。
如果說RV770是翻身之作,那么RV870(Cypress)就是反攻之作,AMD搶先推出DX11顯卡,在NVIDIA GF100陷入大核心低良率的泥潭時(shí),大舉收復(fù)失地。
RV870是AMD近年來最成功的一顆GPU核心,但它的成功是拜NVIDIA的失誤所賜,RV870核心本身可以說是毫無新意,因?yàn)樗耆褪荝V770的兩倍規(guī)格,除了顯存控制器以外的所有模塊統(tǒng)統(tǒng)翻倍,AMD沿用RV770暴力擴(kuò)充流處理器的路線,繼續(xù)提高運(yùn)算能力,搶灘登陸DX11。
RV870核心架構(gòu)圖
把RV870與RV770的架構(gòu)圖放一起的話,可以發(fā)現(xiàn)其外圍周邊模塊幾乎完全相同,而流處理器部分是一分為二的設(shè)計(jì),其中的一半正好就是RV770的規(guī)格。
除了加入DX11、ShaderModel 5.0的支持,賦予Eyefinity 6屏輸出的功能外,RV870與RV770相比并沒有本質(zhì)改進(jìn)。
既然流處理器部分還是維持R600的設(shè)計(jì),那就不用期待它在并行計(jì)算方面能有什么改進(jìn)。AMD依然我行我素的在搞通用計(jì)算,支持的軟件還是那么幾款。RV870理論浮點(diǎn)運(yùn)算能力再創(chuàng)新高,但卻沒什么人用,中國最強(qiáng)的超級(jí)計(jì)算機(jī)天河一號(hào)曾經(jīng)使用的是HD4870X2,但后來升級(jí)成天河一號(hào)A之后改用了NVIDIA的Tesla,就是活生生的例子。
也許有人會(huì)問,如此暴力的擴(kuò)充流處理器規(guī)模而不更改架構(gòu),R600架構(gòu)會(huì)成為AMD的常青樹嗎?難道不會(huì)有什么瓶頸嗎?當(dāng)然會(huì)有,AMD也發(fā)現(xiàn)了,所以從HD6000系列開始又進(jìn)行了一輪架構(gòu)的微調(diào),透過AMD架構(gòu)微調(diào)這一結(jié)果,我們可以了解出現(xiàn)問題原因到底是什么?
HD6870的一小步:兩個(gè)超線程分配處理器
Barts核心的HD6870率先問世,這顆核心定位中端,所以流處理器從Cypress的1600個(gè)精簡到了1120個(gè),流處理器結(jié)構(gòu)依然沒有任何變化,但是前端控制模塊一分為二:
相信大家應(yīng)該注意到了,以往AMD的SIMD架構(gòu)則是整顆GPU共享單一的控制單元,自R600以來都是如此。
Cypress的單一圖形裝配引擎
但隨著晶體管規(guī)模和流處理器數(shù)量的迅速膨脹,單一的控制單元已經(jīng)無法滿足大規(guī)模并行指令分配的需要,因此從Cypress開始,AMD采用了“雙核心”的設(shè)計(jì),將SIMD陣列一分為二,也就是類似于NVIDIA GPC的設(shè)計(jì)。與此相對(duì)應(yīng)的,圖形裝配引擎雖然只有一個(gè),內(nèi)部卻設(shè)計(jì)了兩個(gè)Hierarchical Z(分層消影器)和Rasterizer(光柵器),但是其它的特殊功能模塊均只有一個(gè)。
Barts和Cypress一樣,依然保持了雙核心設(shè)計(jì),圖形引擎也只有一個(gè),內(nèi)部的功能模塊并沒有太多變化。但是Ultra-Treaded Dispatch Processor(超線程分配處理器)卻變成了兩個(gè),相對(duì)應(yīng)的,超線程分配處理器的指令緩存也變成了兩份。
Barts的圖形裝配引擎
我們知道,Barts的流處理器數(shù)量是Cypress的70%,按理說線程分配壓力有所下降,那么設(shè)計(jì)兩個(gè)線程分配處理器的目的只有一個(gè),那就是提升效率。在DX11時(shí)代,幾何著色再加上曲面細(xì)分單元引入之后,圖形裝配引擎會(huì)產(chǎn)生更多的并行線程及指令轉(zhuǎn)交SIMD進(jìn)行處理,因此指令派發(fā)效率成為了新的瓶頸。
SIMD架構(gòu)的優(yōu)勢就是可以用較少的晶體管制造成龐大的流處理器規(guī)模,擁有恐怖的理論運(yùn)算能力;但缺點(diǎn)就是流處理器執(zhí)行效率比MIMD架構(gòu)低,其效率高低完全依賴于分配單元的派發(fā)效率。因此Barts這種雙線程分配處理器的設(shè)計(jì)意義重大。
雙超線程分配處理器的意義:曲面細(xì)分性能翻倍
HD6000系列可以說是半代改進(jìn)的架構(gòu),既然數(shù)量上維持不變,就只能從改進(jìn)效率的方面考慮了。而改進(jìn)的內(nèi)容就是加強(qiáng)線程管理和緩沖,也就是“雙倍的超線程分配處理器和指令緩存”。
根據(jù)AMD官方提供的數(shù)據(jù)來看,HD6870的曲面細(xì)分性能最多可達(dá)HD5870的兩倍,這種情況出現(xiàn)在10級(jí)左右的中等細(xì)分程度,當(dāng)曲面細(xì)分達(dá)到20級(jí)以上的時(shí)候,那么它們的性能就基本上沒有區(qū)別了。
由此可見,Barts核心當(dāng)中的Tessellator單元本身在性能方面應(yīng)該沒有改進(jìn),其性能提升主要源于兩顆超線程分配處理器。中等級(jí)別的曲面細(xì)分在指令分配方面是瓶頸,Barts改進(jìn)的架構(gòu)消除了這一瓶頸,所以性能提升十分顯著,但如果細(xì)分級(jí)別特別高時(shí),Tessellator本身的運(yùn)算能力將成為瓶頸,此時(shí)線程派遣器的效率再高,也無濟(jì)于事。
看起來,AMD迫切的想要改進(jìn)指令派發(fā)效率,以滿足龐大規(guī)模流處理器的胃口,并且有效的提升備受詬病的曲面細(xì)分性能。AMD的做法就是繼續(xù)保持現(xiàn)有架構(gòu)不變,發(fā)現(xiàn)瓶頸/缺陷然后消除瓶頸/缺陷,這讓筆者想起了一段老話:“新三年舊三年,縫縫補(bǔ)補(bǔ)又三年”。
相信有些讀者很早就想問這樣一個(gè)問題了:既然圖形渲染的主要指令是4D矢量格式,那為什么R600要設(shè)計(jì)成5D的流處理器結(jié)構(gòu)呢?還沿用了5代之久?有結(jié)果就有原因,通過對(duì)Cayman核心的分析,我們可以找到答案。
R600為什么是5D VLIW結(jié)構(gòu)?
在5D VLIW流處理器中,其中的1個(gè)比較“胖”的ALU有別于其它4個(gè)對(duì)等的ALU,它負(fù)責(zé)執(zhí)行特殊功能(例如三角函數(shù))。而另外4個(gè)ALU可以執(zhí)行普通的加、乘、乘加或融合指令。
Barts核心的流處理器結(jié)構(gòu)
從R600開始的Shader是4D+1D的非對(duì)等設(shè)計(jì),ATI這樣做的目的是為了讓頂點(diǎn)著色器更有效率,以便能同時(shí)處理一個(gè)4D矢量點(diǎn)積(比如w、x、y、z)和一個(gè)標(biāo)量分量(比如光照)。
Cayman核心返璞歸真,改用4D結(jié)構(gòu)
隨著DX10及DX11大行其道,AMD通過自己長期內(nèi)部測試發(fā)現(xiàn),VLIW5架構(gòu)的五個(gè)處理槽中平均只能用到3.4個(gè),也就是在游戲里會(huì)有1.6個(gè)白白浪費(fèi)了。顯然,DX9下非常理想的VLIW5設(shè)計(jì)已經(jīng)過時(shí),它太寬了,必須縮短流處理器單元(SPU),重新設(shè)計(jì)里邊的流處理器(SP)布局。
Cayman核心的流處理器結(jié)構(gòu)
于是Cayman核心誕生了,胖ALU下崗,只保留了剩下4個(gè)對(duì)等的全功能ALU。裁員歸裁員,原來胖ALU的工作還得有人干,Cayman的4D架構(gòu)在執(zhí)行特殊功能指令時(shí),需要占用3個(gè)ALU同時(shí)運(yùn)算。
5D改4D之后最大的改進(jìn)就是,去掉了體積最大的ALU,原本屬于它的晶體管可以用來安放更多的SIMD引擎,據(jù)AMD官方稱流處理器單元的性能/面積比可以提升10%。而且現(xiàn)在是4個(gè)ALU共享1個(gè)指令發(fā)射端口,指令派發(fā)壓力驟減,執(zhí)行效率提升。雙精度浮點(diǎn)運(yùn)算能力也從原來單精度的1/5提高到了1/4。
效率更進(jìn)一步:雙圖形引擎
前面介紹過,從RV770到Cypress核心,圖形引擎和超線程分配處理器都只有一個(gè),但圖形引擎內(nèi)部的Hierarchical Z(分層消影器)和Rasterizer(光柵器)分為兩份。
到了Barts核心,超線程分配處理器從一個(gè)變成兩個(gè)。現(xiàn)在的Cayman核心則更進(jìn)一步,圖形引擎也變成了兩個(gè),也就是除了分層消影器和光柵器外,幾何著色指令分配器、頂點(diǎn)著色指令分配器、還有曲面細(xì)分單元都變成了兩份:
兩個(gè)曲面細(xì)分單元再加上兩個(gè)超線程分配處理器,AMD官方稱HD6970的曲面細(xì)分性能可以達(dá)到HD6870的兩倍、HD5870的三倍。其它方面比如頂點(diǎn)著色、幾何著色性能都會(huì)有顯著的提升。
通用計(jì)算效能也有改進(jìn)
和Cypress、Barts相比,Cayman在通用計(jì)算方面也有一定程度的改進(jìn),主要體現(xiàn)在具備了一定程度的多路并行執(zhí)行能力;雙路DMA引擎可以同時(shí)透過外部總線和本地顯存讀寫數(shù)據(jù);改進(jìn)的流控制提高了指令執(zhí)行效率和運(yùn)算單元浪費(fèi);當(dāng)然雙精度運(yùn)算能力的提高對(duì)于科學(xué)計(jì)算也大有裨益。
不過,這些改進(jìn)都是治標(biāo)不治本,VLIW架構(gòu)從5D到4D只是一小步,只能一定程度上的提高指令執(zhí)行效率,而無法根治GPU編程困難、復(fù)雜指令和條件指令的兼容性問題。總的來說,Cayman核心依然只是單純?yōu)橛螒蚨O(shè)計(jì)的GPU,AMD把5D改為4D也是基于提升3D渲染性能的考慮。
AMD的GPU架構(gòu)介紹了這么多,對(duì)于其優(yōu)缺點(diǎn)也心知肚明了,之前筆者反復(fù)提到了“效率”二字,其參照物當(dāng)然就是NVIDIA的GPU,現(xiàn)在我們就來看看NVIDIA的GPU架構(gòu)有什么特點(diǎn),效率為什么會(huì)比較高?為什么更適合并行計(jì)算?
SIMD效率不高的根本原因
無論AMD怎么調(diào)整架構(gòu),5D還是4D的結(jié)構(gòu)都還是SIMD,也就是這4-5個(gè)ALU要共用一個(gè)指令發(fā)射端口,這樣就對(duì)GPU指令派發(fā)器提出了很高的要求:如果沒有把4-5個(gè)指令打包好發(fā)送到過來,那么運(yùn)算單元就不會(huì)全速運(yùn)行;如果發(fā)送過來的4-5個(gè)指令當(dāng)中包含條件指令,但運(yùn)行效率就會(huì)降至連50%都不到,造成災(zāi)難性的資源浪費(fèi)。
解決方法也不是沒有,但都治標(biāo)不治本,需要對(duì)游戲/程序本身進(jìn)行優(yōu)化,盡量避免使用標(biāo)量指令、條件指令和混合指令,驅(qū)動(dòng)為程序?qū)iT做優(yōu)化,難度可想而知。
而治本的方法就是拋棄SIMD架構(gòu),從源頭上解決指令組合預(yù)分配的問題。
G80革命性的MIMD架構(gòu)
NVIDIA的科學(xué)家對(duì)圖形指令結(jié)構(gòu)進(jìn)行了深入研究,它們發(fā)現(xiàn)標(biāo)量數(shù)據(jù)流所占比例正在逐年提升,如果渲染單元還是堅(jiān)持SIMD設(shè)計(jì)會(huì)讓效率下降。為此NVIDIA在G80中做出大膽變革:流處理器不再針對(duì)矢量設(shè)計(jì),而是統(tǒng)統(tǒng)改成了標(biāo)量ALU單元,這種架構(gòu)叫做MIMD(Multiple Instruction Multiple Data,多指令多數(shù)據(jù)流)
G80核心架構(gòu),每個(gè)流處理器就是一個(gè)標(biāo)量ALU
如此一來,對(duì)于依然占據(jù)主流的4D矢量操作來說,G80需要讓1個(gè)流處理器在4個(gè)周期內(nèi)才能完成,或者是調(diào)動(dòng)4個(gè)流處理器在1個(gè)周期內(nèi)完成,那么G80的執(zhí)行效率豈不是很低?沒錯(cuò),所以NVIDIA大幅提升了流處理器工作頻率(兩倍于核心頻率),擴(kuò)充了流處理器的規(guī)模(128個(gè)),這樣G80的128個(gè)標(biāo)量流處理器的運(yùn)算能力就基本相當(dāng)于傳統(tǒng)的64個(gè)(128×2?)4D矢量ALU。大家應(yīng)該知道R600擁有64個(gè)5D矢量ALU,最終的性能G80要遠(yuǎn)勝R600。
當(dāng)然這只是在處理4D指令時(shí)的情形,隨著圖形畫面越來越復(fù)雜,1D、2D、3D指令所占比例正在逐年增多,而G80在遇到這種指令時(shí)可說是如魚得水,與4D一樣不會(huì)有任何效能損失,指令轉(zhuǎn)換效率高并且對(duì)指令的適應(yīng)性非常好,這樣G80就將GPU Shader執(zhí)行效率提升到了新的境界!
MIMD架構(gòu)的劣勢
G80的架構(gòu)聽起來很完美,但也存在不可忽視的缺點(diǎn):根據(jù)前面的分析可以得知,4個(gè)1D標(biāo)量ALU和1個(gè)4D矢量ALU的運(yùn)算能力是相當(dāng)?shù)?,但是前者需?個(gè)指令發(fā)射端和4個(gè)控制單元,而后者只需要1個(gè),如此一來MIMD架構(gòu)所占用的晶體管數(shù)將遠(yuǎn)大于SIMD架構(gòu)!
所以AMD的SIMD架構(gòu)可以用較少的晶體管造出龐大數(shù)量的流處理器、擁有恐怖的理論浮點(diǎn)運(yùn)算能力;而NVIDIA的MIMD架構(gòu)必須使用更多的晶體管制造出看似比較少的流處理器,理論浮點(diǎn)運(yùn)算能力相差很遠(yuǎn)。雙方走的都是極端路線,AMD以數(shù)量彌補(bǔ)效率的不足,而NVIDIA以效率彌補(bǔ)數(shù)量的劣勢。
G80的MIMD架構(gòu)開了一個(gè)好頭,128個(gè)流處理器雖然聽起來雖然沒有AMD 320個(gè)那么多,但這些流處理器是可以媲美真正的CPU核心,在執(zhí)行任何指令時(shí)都能發(fā)揮出接近理論值的性能,這樣高效率的核心如果只是用來玩游戲豈不太可惜了?
于是在游戲市場大獲全勝的NVIDIA并沒有止步于此,而是將目光放在了更長遠(yuǎn)的高性能計(jì)算領(lǐng)域,一邊著手開發(fā)基于GPU計(jì)算的應(yīng)用程序中間件,幫助程序員以更高效的方式開發(fā)基于GPU硬件加速的軟件,另一方面在G80的基礎(chǔ)上繼續(xù)優(yōu)化核心架構(gòu),將MIMD架構(gòu)高效率的優(yōu)勢發(fā)揮到極致!
GT200核心:真正的并行計(jì)算架構(gòu)
G80依然只是為DX10 3D渲染而設(shè)計(jì)的,雖然MIMD架構(gòu)本身能夠勝任并行數(shù)據(jù)計(jì)算的需要,但NVIDIA發(fā)現(xiàn)圖形架構(gòu)還有繼續(xù)改進(jìn)的余地,只要在核心內(nèi)部設(shè)計(jì)全新的控制模塊,并對(duì)微架構(gòu)進(jìn)行專門的優(yōu)化,就能將GPU的圖形架構(gòu)改造成更加適合非圖形領(lǐng)域的并行數(shù)據(jù)處理架構(gòu)。
第一代統(tǒng)一渲染架構(gòu)的主要目的是把原本像素著色、頂點(diǎn)著色以及新增的幾何著色,統(tǒng)一交給流處理器來處理。而NVIDIA的GT200核心則被稱為第二代統(tǒng)一渲染架構(gòu),其主要含義就是將圖形處理架構(gòu)和并行計(jì)算架構(gòu)完美的結(jié)合起來,成為一顆真正意義上的通用處理器,超越圖形處理器的概念!
GT200相對(duì)于G80,不止是把流處理器數(shù)量從128個(gè)擴(kuò)充到240個(gè)這么簡單,其實(shí)最關(guān)鍵之處是對(duì)TPC(線程處理器簇)和SM(流處理器簇)的改進(jìn):
新增Atomic原子操作:透過原子操作,硬?;蟮木€程操作管理將更加有序和具體,這也就意味著像素或者其他類型如通用計(jì)算應(yīng)用的Thread的生成、仲裁、泵送、內(nèi)存位置確定和執(zhí)行過程都將變得更加精確和高效,Atomic單元和原子操作的引入也為未來NVIDIA構(gòu)架最終實(shí)現(xiàn)并行化設(shè)計(jì)起到了關(guān)鍵的先導(dǎo)作用。
每個(gè)SM可執(zhí)行線程上限提升:G80/G92核心每個(gè)SM(即不可拆分的8核心流處理器)最多可執(zhí)行768條線程,而GTX200核心的每個(gè)SM提升至1024條,而且GTX200擁有更多的SM,芯片實(shí)力達(dá)到原來的2.5倍!
每個(gè)SM的指令寄存器翻倍:GTX200與G80核心在SM結(jié)構(gòu)上基本相同的,但功能有所提升,在執(zhí)行線程數(shù)增多的同時(shí),NVIDIA還將每個(gè)SM中間的Local Memory容量翻倍(從16K到32K)。Local Memory用于存儲(chǔ)SM即將執(zhí)行的上千條指令,容量增大意味著可以存儲(chǔ)更多的指令、超長的指令、或是各種復(fù)雜的混合式指令,這對(duì)于提高SM的執(zhí)行效能大有裨益。
DX10游戲會(huì)越來越多的使用復(fù)雜的混合式Shader指令,一旦排隊(duì)中的超長指令溢出或者在N個(gè)周期內(nèi)都排不上隊(duì),那么就會(huì)造成效率下降的情況,此時(shí)雙倍寄存器容量的優(yōu)勢就體現(xiàn)出來了。由于Local Memory并不會(huì)消耗太多晶體管,因此將其容量翻倍是很合算的。
紋理單元數(shù)量提升,比率下降,達(dá)到了ATI當(dāng)年鼓吹的3:1水平
其它改進(jìn)還有:幾何著色性能提升,提高雙指令執(zhí)行(Dual-Issue)效率,達(dá)到93%-94%之多,支持雙精度64Bit浮點(diǎn)運(yùn)算,運(yùn)算能力為單精度的1/8。
綜合來看,GT200除了流處理器、紋理單元、光柵單元這些硬貨數(shù)量增多對(duì)游戲性能大有裨益以外,其它細(xì)節(jié)部分的優(yōu)化跟游戲關(guān)系不大。因?yàn)镚T200是為并行計(jì)算而設(shè)計(jì)的,從GT200開始,GPU計(jì)算變得更加實(shí)用和普及,NVIDIA的Tesla開始進(jìn)入科學(xué)實(shí)驗(yàn)室,并殺進(jìn)超級(jí)計(jì)算機(jī)市場。
隨著Tesla在高性能計(jì)算領(lǐng)域日漸深入人心,NVIDIA也在與科研工作者們進(jìn)行深入的溝通,傾聽一線用戶的需求,以便在下代GPU核心中做出相應(yīng)的優(yōu)化改進(jìn)。當(dāng)時(shí)用戶最大的需求有兩點(diǎn):第一,科學(xué)家和超級(jí)計(jì)算只看重64bit雙精度浮點(diǎn)運(yùn)算能力,GT200性能太低,只有單精度的1/8;第二:企業(yè)級(jí)用戶對(duì)穩(wěn)定性要求更高,傳統(tǒng)的顯卡不支持顯存ECC(錯(cuò)誤檢查和糾正),計(jì)算出錯(cuò)后效率較低。
這就是下一代GPU的設(shè)計(jì)目標(biāo)。而且,這次GF100不僅要滿足并行計(jì)算的需求,還要兼顧DX11游戲性能,針對(duì)DX11新增的曲面細(xì)分、幾何運(yùn)算做出相應(yīng)的改進(jìn),時(shí)間緊、任務(wù)重、壓力大。
過于追求完美往往結(jié)果就會(huì)不完美,NVIDIA在GPU架構(gòu)設(shè)計(jì)部分做到了近乎完美,但是在芯片制造端掉了鏈子——由于GPU核心太大,臺(tái)積電40nm工藝還不夠成熟,導(dǎo)致GF100核心良率低下,沒能達(dá)到設(shè)計(jì)預(yù)期,最終的產(chǎn)品不僅功耗發(fā)熱很大,而且規(guī)格不完整。所以雖然當(dāng)時(shí)GTX480顯卡的評(píng)價(jià)不是很高,但GF100核心的架構(gòu)極其優(yōu)秀的。等到工藝成熟之后的GF110核心以及GTX580顯卡,就毫無疑問的站在了游戲與計(jì)算的巔峰!
GF100是“四核心”設(shè)計(jì):4個(gè)光柵化引擎
GF100/110可以看作是四核心設(shè)計(jì)
如果我們把Cayman看作是雙核心的設(shè)計(jì),那GF100就是四核心的設(shè)計(jì),它擁有四個(gè)GPC(圖形處理器集群)模塊,每個(gè)GPC都有各自的光柵化引擎(Raster Engine),而在以往都是整顆GPU共享一個(gè)Raster Engine。
GF100擁有16個(gè)多形體引擎
GF100與GT200最大的不同其實(shí)就是PolyMorph Engine,譯為多形體引擎。每個(gè)SM都擁有一個(gè)多形體引擎,GF100核心總共有多達(dá)16個(gè)。那么多形體引擎是干什么用的呢?為什么要設(shè)計(jì)如此之多?
為什么要這么多的多形體引擎?
之前的GPU架構(gòu)一直都使用單一的前端控制模塊來獲取、匯集并對(duì)三角形實(shí)現(xiàn)光柵化。無論GPU有多少個(gè)流處理器,這種固定的流水線所實(shí)現(xiàn)的性能都是相同的。但應(yīng)用程序的工作負(fù)荷卻是不同的,所以這種流水線通常會(huì)導(dǎo)致瓶頸出現(xiàn),流處理器資源未能得到充分利用。
實(shí)現(xiàn)光柵化并行處理的同時(shí)還要保持API的順序是非常困難的,這種難度阻礙了這一領(lǐng)域的重大創(chuàng)新。雖然單個(gè)前端控制單元的設(shè)計(jì)在過去的GPU中曾有過輝煌的歷史,但是隨著對(duì)幾何復(fù)雜度的需求不斷增長,它現(xiàn)在已經(jīng)變成了一個(gè)主要障礙。
Tessellation的使用從根本上改變了GPU圖形負(fù)荷的平衡,該技術(shù)可以將特定幀中的三角形密度增加數(shù)十倍,給設(shè)置于光柵化單元等串行工作的資源帶來了巨大壓力。為了保持較高的Tessellation性能,有必要重新平衡圖形流水線。
為了便于實(shí)現(xiàn)較高的三角形速率,NVIDIA設(shè)計(jì)了一種叫做“PolyMorph”的可擴(kuò)展幾何引擎。每16個(gè)PolyMorph引擎均擁有自己專用的頂點(diǎn)拾取單元以及鑲嵌器,從而極大地提升了幾何性能。與之搭配的4個(gè)并行光柵化引擎,它們?cè)诿總€(gè)時(shí)鐘周期內(nèi)可設(shè)置最多4個(gè)三角形。同時(shí),它們還能夠在三角形獲取、Tessellation、以及光柵化等方面實(shí)現(xiàn)巨大性能突破。
這是Cayman的圖形引擎,是雙核心設(shè)計(jì)
AMD的Cayman核心是不分光柵化引擎和多形體引擎的,都可以算作是雙核心設(shè)計(jì),GF100與Cayman相比,光柵化引擎是4:1,多形體引擎(包括曲面細(xì)分單元)是16:2,GF100的幾何圖形性能有多么強(qiáng)大已經(jīng)可以想象。
當(dāng)NVIDIA的工程師通過計(jì)算機(jī)模擬測試得知幾何引擎將會(huì)成為DX11新的瓶頸之后,毫不遲疑的選擇了將單個(gè)控制模塊打散,重新設(shè)計(jì)了多形體引擎和光柵化引擎,并分散至每組SM或每個(gè)GPC之中,從而大幅提升了幾何性能,徹底消除了瓶頸。
GF100流處理器部分的改進(jìn)
每一個(gè)CUDA核心都擁有一個(gè)完全流水線化的整數(shù)算術(shù)邏輯單元(ALU)以及浮點(diǎn)運(yùn)算單元(FPU)。GF100采用了最新的IEEE754-2008浮點(diǎn)標(biāo)準(zhǔn),2008標(biāo)準(zhǔn)的主要改進(jìn)就是支持多種類型的舍入算法。新標(biāo)準(zhǔn)可以只在最終獲取數(shù)據(jù)時(shí)進(jìn)行四舍五入,而以往的標(biāo)準(zhǔn)是每進(jìn)行一步運(yùn)算都要四舍五入一次,最后會(huì)產(chǎn)生較大的誤差。
GF100能夠?yàn)?2bit單精度和64bit雙精度運(yùn)算提供FMA(Fused Multiply-Add,積和熔加)指令,而GT200只在64bit時(shí)才能提供。FMA不僅適用于高性能計(jì)算領(lǐng)域,事實(shí)上在渲染緊密重疊的三角形時(shí),新的FMA算法能夠最大限度的減少渲染誤差。
ATI所有的流處理器在執(zhí)行整數(shù)型加、乘指令時(shí)僅支持24bit精度,而NVIDIA CUDA核心支持所有整數(shù)指令全32位精度,符合標(biāo)準(zhǔn)編程語言的基本要求。整數(shù)ALU還經(jīng)過了優(yōu)化,可有效支持64位以及更高精度的運(yùn)算,這一點(diǎn)是對(duì)手無法比擬的。
GF100擁有雙Warp調(diào)度器可選出兩個(gè)Warp,從每個(gè)Warp發(fā)出一條指令到16個(gè)核心、16個(gè)載入/存儲(chǔ)單元或4個(gè)特殊功能單元。因?yàn)閃arp是獨(dú)立執(zhí)行的,所以GF100的調(diào)度器無需檢查指令流內(nèi)部的依存關(guān)系。通過利用這種優(yōu)秀的雙指令執(zhí)行(Dual-issue)模式,GF100能夠?qū)崿F(xiàn)接近峰值的硬件性能。
GF100首次引入一級(jí)緩存與動(dòng)態(tài)共享緩存
GF100核心擁有很多種類的緩存,他們的用途不盡相同,其中一級(jí)緩存、共享緩存和紋理緩存位于SM內(nèi)部,二級(jí)緩存則是獨(dú)立的一塊,與光柵單元及顯存控制器相連。
以往的GPU都是沒有一級(jí)緩存的,只有一級(jí)紋理緩存,因?yàn)檫@些緩存無法在通用計(jì)算中用于存儲(chǔ)計(jì)算數(shù)據(jù),只能用于在紋理采樣時(shí)暫存紋理。而在GF100當(dāng)中,NVIDIA首次引入真正的一級(jí)高速緩存,而且還可被動(dòng)態(tài)的劃分為共享緩存。
在GF100 GPU中,每個(gè)SM除了擁有專用的紋理緩存外,還擁有64KB容量的片上緩存,這部分緩存可配置為16KB的一級(jí)緩存+48KB共享緩存,或者是48KB一級(jí)緩存+16KB共享緩存。這種劃分方式完全是動(dòng)態(tài)執(zhí)行的,一個(gè)時(shí)鐘周期之后可自動(dòng)根據(jù)任務(wù)需要即時(shí)切換而不需要程序主動(dòng)干預(yù)。
一級(jí)緩存與共享緩存是互補(bǔ)的,共享緩存能夠?yàn)槊鞔_界定存取數(shù)據(jù)的算法提升存取速度,而一級(jí)緩存則能夠?yàn)橐恍┎灰?guī)則的算法提升存儲(chǔ)器存取速度。在這些不規(guī)則算法中,事先并不知道數(shù)據(jù)地址。
對(duì)于圖形渲染來說,重復(fù)或者固定的數(shù)據(jù)比較多,因此一般是劃分48KB為共享緩存,當(dāng)然剩下的16KB一級(jí)緩存也不是完全沒用,它可以充當(dāng)寄存器溢出的緩沖區(qū),讓寄存器能夠?qū)崿F(xiàn)不俗的性能提升。而在并行計(jì)算之中,一級(jí)緩存與共享緩存同樣重要,它們可以讓同一個(gè)線程塊中的線程能夠互相協(xié)作,從而促進(jìn)了片上數(shù)據(jù)廣泛的重復(fù)利用并減少了片外的通信量。共享存儲(chǔ)器是使許多高性能CUDA應(yīng)用程序成為可能的重要促成因素。
GF100擁有一個(gè)768KB容量統(tǒng)一的二級(jí)高速緩存,該緩存可以為所有載入、存儲(chǔ)以及紋理請(qǐng)求提供服務(wù)。二級(jí)緩存可在整個(gè)GPU中提供高效、高速的數(shù)據(jù)共享。物理效果、光線追蹤以及稀疏數(shù)據(jù)結(jié)構(gòu)等事先不知道數(shù)據(jù)地址的算法在硬件高速緩存上的運(yùn)行優(yōu)勢尤為明顯。后期處理過濾器需要多個(gè)SM才能讀取相同的數(shù)據(jù),該過濾器與存儲(chǔ)器之間的距離更短,從而提升了帶寬效率。
統(tǒng)一的共享式緩存比單獨(dú)的緩存效率更高。在獨(dú)享式緩存設(shè)計(jì)中,即使同一個(gè)緩存被多個(gè)指令預(yù)訂,它也無法使用其它緩存中未貼圖的部分。高速緩存的利用率將遠(yuǎn)低于它的理論帶寬。GF100的統(tǒng)一共享式二級(jí)高速緩存可在不同請(qǐng)求之間動(dòng)態(tài)地平衡負(fù)載,從而充分地利用緩存。二級(jí)高速緩存取代了之前GPU中的二級(jí)紋理緩存、ROP緩存以及片上FIFO。
GF100的緩存架構(gòu)讓各流水線之間可以高效地通信,減少了顯存讀寫操作
統(tǒng)一的高速緩存還能夠確保存儲(chǔ)器按照程序的順序執(zhí)行存取指令。當(dāng)讀、寫路徑分離(例如一個(gè)只讀紋理路徑以及一個(gè)只寫ROP路徑)時(shí),可能會(huì)出現(xiàn)先寫后讀的危險(xiǎn)。一個(gè)統(tǒng)一的讀/寫路徑能夠確保程序的正確運(yùn)行,同時(shí)也是讓NVIDIA GPU能夠支持通用C/C++程序的重要因素。
與只讀的GT200二級(jí)緩存相比,GF100的二級(jí)高速緩存既能讀又能寫,
而且是完全一致的。NVIDIA采用了一種優(yōu)先算法來清除二級(jí)緩存中的數(shù)據(jù),這種算法包含了各種檢查,可幫助確保所需的數(shù)據(jù)能夠駐留在高速緩存當(dāng)中。
之所以要對(duì)NVIDIA的GF100/110核心進(jìn)行重點(diǎn)介紹,是因?yàn)樗且粋€(gè)很好的參照物,接下來要介紹的Tahiti核心很多方面都會(huì)與GF100進(jìn)行對(duì)比,看看AMD所謂的GCN(次世代圖形核心)到底有多么先進(jìn)。
Tahiti的核心架構(gòu)圖
這是AMD官方公布的Tahiti核心架構(gòu)圖,第一眼看上去,我們就會(huì)發(fā)現(xiàn)他與以往所有的AMD GPU架構(gòu)有了明顯區(qū)別,無論圖形引擎部分還是流處理器部分都有了天翻地覆的變化,如果沒有右側(cè)熟悉的UVD、CrossFire、Eyefinity等功能模塊,很難相信這是一顆AMD的GPU。
先看看最上面的圖形引擎部分
Tahiti的圖形引擎部分
Cayman的圖形引擎部分
這一部分Tahiti幾乎沒有什么變化,依然是雙圖形引擎的設(shè)計(jì),幾何著色指令分配器、頂點(diǎn)著色指令分配器、曲面細(xì)分單元、光柵器、分層消影器都是雙份的設(shè)計(jì)。
毫不起眼但意義重大的改進(jìn):雙ACE
除此之外,還有一個(gè)毫不起眼但是意義重大的改進(jìn),那就是在圖形引擎上方加入了兩個(gè)ACE(Asynchronous Compute Engine,異步計(jì)算引擎),這兩個(gè)引擎直接與指令處理器、幾何引擎及全局?jǐn)?shù)據(jù)緩存相連,作用是管理GPU的任務(wù)隊(duì)列,將線程分門別類的分發(fā)給流處理器。
ACE將會(huì)充當(dāng)指令處理器的角色用于運(yùn)算操作,而ACE的主要作用就是接受任務(wù)并將其下遣分配給流處理器(主要是分配的過程)。全新架構(gòu)強(qiáng)化了多任務(wù)的并行處理設(shè)計(jì),資源分配、上下文切換以及任務(wù)優(yōu)先級(jí)決策等等。ACE的直接作用就是新架構(gòu)擁有了一定程度的亂序執(zhí)行能力,雖然嚴(yán)格意義上新架構(gòu)依然是順序執(zhí)行架構(gòu),一個(gè)完整線程中的指令執(zhí)行順序不能被打亂,但是ACE可以做到對(duì)不同的任務(wù)進(jìn)行優(yōu)化和排序,劃分任務(wù)執(zhí)行的優(yōu)先級(jí)別,進(jìn)而優(yōu)化資源。從本質(zhì)上來說,這與很多CPU(比如Atom、ARM A8等等)處理多任務(wù)的方式并沒有什么不同。
而且ACE的加入大幅提升了Tahiti的幾何性能,并且使得通用計(jì)算時(shí)的指令分配更加有序和并行化,緩存使用率和命中率更高。
有針對(duì)性的強(qiáng)化曲面細(xì)分單元
單從數(shù)量上來看,Tahiti明顯不如GF100的4個(gè)光柵化引擎(光柵器+分層消影器)以及8個(gè)多形體引擎(幾何/頂點(diǎn)分配器及曲面細(xì)分單元等)。不過AMD有針對(duì)性的強(qiáng)化了曲面細(xì)分單元,通過提高頂點(diǎn)的復(fù)用率、增強(qiáng)片外緩存命中率、以及更大參數(shù)高速緩存的配合下,HD7970在所有級(jí)別的曲面細(xì)分環(huán)境下都可以達(dá)到4倍于HD6970的性能:
此前我們介紹過,HD6970的曲面細(xì)分性能是HD6870的兩倍、HD5870的三倍。通過AMD的理論數(shù)據(jù)來看,Tahiti的曲面細(xì)分性能應(yīng)該達(dá)到甚至超越了GF100/110。
看得出來,AMD的Tahiti在圖形引擎方面依然沿用Cayman的設(shè)計(jì),從Cypress到Barts再到Cayman,AMD穩(wěn)扎穩(wěn)打的對(duì)圖形引擎進(jìn)行優(yōu)化與改進(jìn),AMD認(rèn)為現(xiàn)有的雙圖形引擎設(shè)計(jì)足以滿足流處理器的需要,因此只對(duì)備受詬病的曲面細(xì)分模塊進(jìn)行了改良,如此有針對(duì)性的設(shè)計(jì)算是亡羊補(bǔ)牢、為時(shí)不晚。
看了上頁圖形引擎部分的介紹,很多人可能會(huì)失望——基本沒動(dòng)嘛,還說什么次世代圖形核心?別著急,好戲在后頭。我們知道AMD歷代GPU的瓶頸除了曲面細(xì)分以外,其實(shí)最重要的是5D/4D VLIW架構(gòu)的效率問題?,F(xiàn)在Tahiti的GCN架構(gòu)就是要解決這個(gè)問題,它的流處理器結(jié)構(gòu)已經(jīng)面目全非了。
Tahiti徹底拋棄VLIW架構(gòu)
通過Tahiti的整體架構(gòu)圖我們看到,傳統(tǒng)的SIMD流處理器陣列消失了,取而代之的是GCN陣列,Tahiti總計(jì)擁有2048個(gè)流處理器,這樣每個(gè)GCN陣列里面擁有64個(gè)流處理器?,F(xiàn)在來看看GCN陣列的微觀結(jié)構(gòu)。
GCN與GF100的SM何其相似
Tahiti的GCN陣列微觀結(jié)構(gòu)
GCN陣列里有4組SIMD單元,每組SIMD單元里面包括16個(gè)流處理器、或者說是標(biāo)量運(yùn)算器。GCN架構(gòu)已經(jīng)完全拋棄了此前5D/4D流處理器VLIW超長指令架構(gòu)的限制,不存在5D/4D指令打包-派發(fā)-解包的問題,所有流處理器以16個(gè)為一組SIMD陣列完成指令調(diào)度。簡單來說,以往是指令集并行,而現(xiàn)在是線程級(jí)并行。
GF100的SM(流處理器簇)微觀結(jié)構(gòu)
可以這么理解,一個(gè)GCN陣列與GF100當(dāng)中的一組SM相當(dāng),GF100的一組SM當(dāng)中有4組共計(jì)32個(gè)流處理器,而Tahiti的一組GCN當(dāng)中有4組共計(jì)64個(gè)流處理器。
緩存部分
每個(gè)SIMD-16單元都擁有64KB向量寄存器
每組GCN陣列擁有64KB的本地?cái)?shù)據(jù)共享緩存,還有16KB的一級(jí)緩存
每組GCN陣列有一個(gè)標(biāo)量運(yùn)算單元,用于執(zhí)行整數(shù)指令、媒體指令和浮點(diǎn)原子操作,這個(gè)標(biāo)量運(yùn)算單元擁有自己的4KB寄存器
而GF100的緩存設(shè)計(jì)得更加靈活,每組SM里面擁有總計(jì)64KB的共享緩存+一級(jí)緩存,這64KB緩存可以根據(jù)實(shí)際運(yùn)算量來動(dòng)態(tài)調(diào)整,如果把16KB分配給一級(jí)緩存的話,那剩下的48KB就是共享緩存,反之亦然。
一般來說,進(jìn)行圖形渲染時(shí)需要共享緩存比較多,而并行計(jì)算時(shí)則會(huì)用到更多的一級(jí)緩存。GF100這種靈活的緩存分配機(jī)制更適合做并行計(jì)算,而GCN架構(gòu)更大的共享緩存會(huì)有更好的圖形渲染性能,并行計(jì)算則會(huì)稍遜一籌。
更多的線程調(diào)度
從緩存部分的設(shè)計(jì)來看,雖然GCN擁有更大的緩存容量,但在并行計(jì)算領(lǐng)域經(jīng)營多年的NVIDIA顯然要棋高一手。
從線程級(jí)別來看,GCN與SM是不可分割的最小單元,GCN一次可以執(zhí)行64個(gè)線程,而SM是48個(gè)(其實(shí)就是流處理器的數(shù)量)。
從多線程執(zhí)行上來看,GCN可以同時(shí)執(zhí)行4個(gè)硬件線程,而SM是雙線程調(diào)度器的設(shè)計(jì)(參見架構(gòu)圖)。
如此來看,GCN架構(gòu)的多線程性能會(huì)更好一些。
小結(jié):AMD GCN抄襲NVIDIA SM架構(gòu)?
在流處理器部分,終于不用費(fèi)勁的把AMD和NVIDIA GPU架構(gòu)分開介紹了,因?yàn)镚CN與SM已經(jīng)沒有本質(zhì)區(qū)別。剩下的只是緩存容量、流處理器簇的數(shù)量、線程調(diào)度機(jī)制的問題,雙方根據(jù)實(shí)際應(yīng)用自然會(huì)有不同的判斷,自家的前后兩代產(chǎn)品也會(huì)對(duì)這些數(shù)量和排列組合進(jìn)行微調(diào)。
AMD向NVIDIA的架構(gòu)靠攏,證明了他這么多年來確實(shí)是在錯(cuò)誤的道路上越走越遠(yuǎn),還好浪子回頭金不換,這次GCN架構(gòu)簡直就是大躍進(jìn)!
在流處理器部分,我們看到Tahiti與GF100如此相似,那么接下來看到緩存設(shè)計(jì)時(shí),您可能會(huì)要驚呼了……看圖說話:
Tahiti的緩存結(jié)構(gòu)
Tahiti與GF100緩存的相同之處
先說最直觀的,Tahiti有一個(gè)容量為768KB二級(jí)緩存,這個(gè)容量與GF100的L2完全相同,都可以進(jìn)行讀寫操作。
上頁說過,Tahiti的每組GCN陣列擁有16KB的一級(jí)緩存,GF100的SM里面也有16KB的一級(jí)緩存;每組GCN擁有64KB的本地?cái)?shù)據(jù)共享緩存,GF100的每組SM擁有48KB。
Tahiti總共擁有32個(gè)GCN陣列,所以一級(jí)緩存共有512KB,而GF100擁有16個(gè)SM陣列,一級(jí)緩存共有256KB。但別忘了GF100的L1可以是48KB,這樣總共就是768KB了。
Tahiti與GF100緩存的不同之處
雖然Tahiti的緩存層級(jí)設(shè)定與GF100非常相似,但區(qū)別也是有的:
Tahiti的每組GCN需要將16KB一級(jí)緩存當(dāng)作紋理緩存使用,而GF100的每組SM當(dāng)中設(shè)有專用的12KB紋理緩存;
一般來說非圖形渲染不需要用到紋理緩存,而圖形渲染時(shí)又不會(huì)用到一級(jí)緩存,所以Tahiti將一級(jí)緩存與紋理緩存合并的設(shè)計(jì)更優(yōu);但NVIDIA專門設(shè)計(jì)紋理緩存也不是沒有道理,當(dāng)GPU既渲染圖形又要做計(jì)算時(shí),分離式設(shè)計(jì)的效率會(huì)更高,比如PhysX游戲……A卡不支持所以AMD不會(huì)考慮這種情況。
Tahiti整個(gè)GPU擁有一個(gè)32KB的全局?jǐn)?shù)據(jù)共享緩存,這個(gè)是沿用了Cayman的設(shè)計(jì),但容量減半了,而GF100沒有這種緩存。全局?jǐn)?shù)據(jù)共享緩存主要用于不同GCN陣列間線程的數(shù)據(jù)交換,這塊緩存只對(duì)編譯器可見,所以使用率較低,容量減半相信也是處于這個(gè)原因。
最核心的流處理器和緩存部分介紹完畢,剩下的功能模塊就簡單了:
AMD頭一次使用384bit顯存控制器
我們先來回顧一下顯存控制器的發(fā)展史:
NVIDIA:G80(384bit)-G92(256bit)-GT200(512bit)-GF100(384bit)
AMD:R600(512bit)-RV670(256bit)-RV770(256bit)-Cypress(256bit)-Cayman(256bit)
NVIDIA使用過兩次384bit顯存控制器,而AMD自R600 512bit兵敗之后一直堅(jiān)守256bit的設(shè)計(jì),這次Tahiti是頭一次使用384bit這種折衷的位寬。
AMD作為GDDR5顯存標(biāo)準(zhǔn)的制定者之一,對(duì)于顯存特性吃得比較透,因此同樣的顯存顆粒,A卡的顯存頻率一直都遠(yuǎn)高于N卡。此次AMD在位寬上追平NVIDIA,再加上更高的頻率,顯存帶寬達(dá)到了264GB/s,基本上不會(huì)有什么瓶頸了。
光柵單元數(shù)量不變
Tahiti配備了32個(gè)ROPs,數(shù)量與Cayman,每個(gè)周期能完成32個(gè)色彩處理和128個(gè)Z/Stencil 處理,不過得益于有更高的顯存帶寬,在實(shí)際游戲中的性能要比理論值一樣的Cayman快50%,比如抗鋸齒方面。
率先支持DX11.1 API
AMD一直都是激進(jìn)派,憑借與微軟的深度合作,自DX10以后AMD總是能夠第一時(shí)間發(fā)布支持最新API的顯卡,DX10.1/DX11還有現(xiàn)在的DX11都是如此。目前微軟尚未公布DX11.1的改進(jìn)細(xì)節(jié),相信和當(dāng)年的DX10.1一樣不會(huì)有太多質(zhì)的改動(dòng)。
支持PCI-E 3.0總線的意義
至于PCI-E 3.0總線的支持,更是超前,目前只有Intel的X79+i7-3960X平臺(tái)才會(huì)提供PCI-E3.0支持。根據(jù)經(jīng)驗(yàn)來判斷,PCI-E 3.0翻倍的帶寬并不會(huì)給顯卡帶來性能提升,其主要意義還是對(duì)于多卡的支持。試想,如果PCI-E 3.0 X4都可以滿足HD7970的需求的話,那么現(xiàn)有的Z68(搭配IvyBridge處理器)就不會(huì)限制多路交火的性能表現(xiàn),而X79插8塊(如果主板有這么多插槽的話)HD7970做并行計(jì)算也不會(huì)因?yàn)榻涌趲挾a(chǎn)生性能瓶頸。
最后,再來強(qiáng)調(diào)一下AMD拋棄5D/4D VLIW改用全新GCN架構(gòu)的意義
理想狀態(tài)下毫不相干的四組線程執(zhí)行情況
在VLIW的理想情況下,4個(gè)線程分別各自獨(dú)立且毫不相關(guān),可以看到新架構(gòu)和VLIW的執(zhí)行情況和類似,理論上效率都是100%。
非理想狀態(tài)下,條件相關(guān)線程延遲執(zhí)行
但對(duì)于VLIW架構(gòu)來說,不理想的情況就是遇到相關(guān)的指令流,比如兩個(gè)綠色線程,前三個(gè)線程可在一個(gè)周期內(nèi)執(zhí)行,最下方的藍(lán)色只能獨(dú)立執(zhí)行。而對(duì)于新架構(gòu)來說,則不存在這樣的問題。也就是說,采用硬件調(diào)度之后,GCN和SIMD可以允許選擇不同的線程亂序執(zhí)行,這些線程可以來自同一任務(wù),也可以是不同任務(wù)。當(dāng)然,這種“亂序”也不是絕對(duì)的,基本的流程還是要遵守的,比如各個(gè)線程之間的指令必須按順序執(zhí)行,不能打亂也不能分割。
以上就是AMD官方提供的數(shù)據(jù),HD7970的理論運(yùn)算能力相比HD6970提升不過30%,但在GPU計(jì)算應(yīng)用當(dāng)中的性能提升相當(dāng)顯著,可達(dá)兩倍以上!尤其在AES加密解密算法中,速度達(dá)到了4倍以上,架構(gòu)的威力可見一斑!
HD7900會(huì)在WinZIP當(dāng)中有更好的加密壓縮解壓性能
高清視頻實(shí)時(shí)防抖處理
AMD在努力:支持GPU計(jì)算的軟件越來越多
以往的VLIW架構(gòu)在并行任務(wù)處理方面處于劣勢,并且很依賴編譯器和API的支持,擴(kuò)展到OpenCL也受到很大限制。經(jīng)過硬件架構(gòu)的調(diào)整,新的GCN架構(gòu)在并行計(jì)算方面有了很大提高。編譯壓力減輕,硬件調(diào)度的加入使編譯器擺脫了調(diào)度任務(wù);其次是程序優(yōu)化和支持語言擴(kuò)充更見容易;最后是不用在生成VLIW指令和相關(guān)調(diào)度信息,新架構(gòu)最底層的ISA也更加簡單。
從DX10時(shí)代開始,也就是ATI被AMD收購之后,AMD的GPU架構(gòu)一直都沒有大的改動(dòng)。從HD2000到HD6000,大家應(yīng)該會(huì)發(fā)現(xiàn)GPU流處理器部分的結(jié)構(gòu)沒有任何改動(dòng),區(qū)別只是規(guī)模而已。這次AMD能夠徹底拋棄沿用了5年之久的VLIW超長指令集架構(gòu),真的是讓人眼前一亮,真可謂是浪子回頭金不換。
對(duì)于AMD來說,這次真的是一次革命
Tihiti的GPU架構(gòu)改得很徹底,換句話說就是AMD學(xué)得很快,NVIDIA花了5年時(shí)間循序漸進(jìn)的把G80進(jìn)化到了GF100的級(jí)別;而AMD只用了一年時(shí)間,就讓Tahiti達(dá)到甚至部分超越了GF100的水平,真是可喜可賀!
但是AMD還有很長的路要走,硬件雖然很強(qiáng)大、全新的GCN架構(gòu)也掃清了效率低下障礙,但軟件和程序方面還需加把勁。讓AMD欣喜的是OpenCL API的發(fā)展速度比想象中的還要快,以至于NVIDIA打算部分開放CUDA接口??梢灶A(yù)見的是,未來更多的商業(yè)軟件將會(huì)直接使用OpenCL語言編寫,對(duì)于GPU實(shí)現(xiàn)無差別的硬件加速支持,最終比拼的還是架構(gòu)與效率,而不是誰支持的軟件更多一些。
總結(jié):
隨著GPU架構(gòu)越來越復(fù)雜,傳統(tǒng)“半年更新,一年換代”的已經(jīng)過時(shí),再加上先進(jìn)制造工藝的步伐放緩,GPU架構(gòu)更新的周期被大大延長(1年、2年或者更長),我們現(xiàn)在看到的GPU大多是在原有架構(gòu)上“縫縫補(bǔ)補(bǔ)”。對(duì)于現(xiàn)代GPU來說,一次換代并不僅僅是硬件架構(gòu)的革新,更多時(shí)間的是開發(fā)者們對(duì)新架構(gòu)的適應(yīng)以及對(duì)新特性的吸收。
隨著技術(shù)的發(fā)展,圖形和計(jì)算的概念已經(jīng)不再像以往分的那么清楚了,進(jìn)入DX11時(shí)代時(shí)候,全新API和新特性帶來了以往DirectX版本看不到的東西,尤其是大量的圖形特效可以靠GPU的計(jì)算能力進(jìn)行加速,這一切在要求傳統(tǒng)圖形渲染能力的同事,對(duì)GPU的計(jì)算能力要求十分苛刻,而未來圖形架構(gòu)的發(fā)展勢必會(huì)順應(yīng)這一趨勢。由此看來,AMD下定決定進(jìn)行大規(guī)模的架構(gòu)革新也就不奇怪了。
基于GCN架構(gòu)、Tahiti核心的Radeon HD 7970顯卡將在北京時(shí)間1月9日下午1時(shí)正式發(fā)布,由于國外提前發(fā)布的關(guān)系,可能很多朋友已經(jīng)看過國外的測試成績了,但我們將為讀者們獻(xiàn)上最全面的3D游戲性能測試以及并行計(jì)算性能測試,關(guān)注GPU圖形與計(jì)算的朋友不容錯(cuò)過,敬請(qǐng)期待!■<
關(guān)注我們
