第一章:第二代及以後的GPU工作流程簡介簡單(而不一定絕對科學)的說:GPU主要完成對3D圖形的處理--圖形的生成渲染。GPU的圖形(處理)流水線完成如下的工作:(並不一定是按照如下順序)頂點處理:這階段GPU讀取描述3D圖形外觀的頂點資料並根據頂點資料確定3D圖形的形狀及位置關係,建立起3D圖形的骨架。在支援DX8和DX9規格的GPU中,這些工作由硬體實現的Vertex Shader(定點著色器)完成。光柵化計算:顯示器實際顯示的影象是由畫素組成的,我們需要將上面生成的圖形上的點和線透過一定的演算法轉換到相應的畫素點。把一個向量圖形轉換為一系列畫素點的過程就稱為光柵化。例如,一條數學表示的斜線段,最終被轉化成階梯狀的連續畫素點。紋理帖圖:頂點單元生成的多邊形只構成了3D物體的輪廓,而紋理對映(texture mapping)工作完成對多變形表面的帖圖,通俗的說,就是將多邊形的表面貼上相應的圖片,從而生成“真實”的圖形。TMU(Texture mapping unit)即是用來完成此項工作。 畫素處理:這階段(在對每個畫素進行光柵化處理期間)GPU完成對畫素的計算和處理,從而確定每個畫素的最終屬性。在支援DX8和DX9規格的GPU中,這些工作由硬體實現的Pixel Shader(畫素著色器)完成。最終輸出:由ROP(光柵化引擎)最終完成畫素的輸出,1幀渲染完畢後,被送到視訊記憶體幀緩衝區。總結:GPU的工作通俗的來說就是完成3D圖形的生成,將圖形對映到相應的畫素點上,對每個畫素進行計算確定最終顏色並完成輸出。第二章:DirectX8和DirectX9 GPU的傳統流水線前面的工作流程其實已經說明了問題。本章來總結一下,承前啟後。傳統的GPU功能部件我們不妨將其分為頂點單元和畫素流水線兩部分。頂點單元由數個硬體實現的Vertex Shader組成。傳統的畫素流水線由幾組PSU(Pixel Shader Unit)+TMU+ROP組成。於是,傳統的GPU由頂點單元生成多邊形,並由畫素流水線負責畫素渲染和輸出。對於畫素流水線需要做的說明是:雖然傳統的流水線被認為=1PSU+1TMU+1ROP,但這個比例不是恆定的,例如在RadeonX1000(不包括X1800)系列中被廣為稱道的3:1黃金架構,PSU:TMU:ROP的數量為3:1:1。一塊典型的X1900顯示卡具有48個PSU,16個TMU和16個ROP。之所以採用這種設計方法,主要考慮到在當今的遊戲中,畫素指令數要遠遠大於紋理指令的數量。ATI憑藉這個優秀的架構,成功擊敗了Geforce7,在DX9後期取得了3D效能上的領先。總結:傳統的GPU由頂點單元生成多邊形,畫素流水線渲染畫素並輸出,一條畫素流水線包含PSU,TMU,和ROP(有的資料中不包含ROP),比例通常為1:1:1,但不固定。第三章:頂點和畫素操作指令GPU透過執行相應的指令來完成對頂點和畫素的操作。熟悉OpenGL或Direct3D程式設計的人應該知道,畫素通常使用RGB三原色和alpha值共4個通道(屬性)來描述。而對於頂點,也通常使用XYZ和W 4個通道(屬性)來描述。因而,通常執行一條頂點和畫素指令需要完成4次計算,我們這裡成這種指令為4D向量指令(4維)。當然,並不是所有的指令都是4D指令,在實際處理中,還會出現大量的1D標量指令以及2D,3D指令。總結:由於定點和畫素通常用4元組表示屬性,因而頂點和畫素操作通常是4D向量操作,但也存在標量操作。第四章:傳統GPU指令的執行傳統的GPU基於SIMD的架構。SIMD即Single Instruction Multiple Data,單指令多資料。其實這很好理解,傳統的VS和PS中的ALU(算術邏輯單元,通常每個VS或PS中都會有一個ALU,但這不是一定的,例如G70和R5XX有兩個)都能夠在一個週期內(即同時)完成對向量4個通道的運算。比如執行一條4D指令,PS或VS中的ALU對指令對應定點和畫素的4個屬性資料都進行了相應的計算。這便是SIMD的由來。這種ALU我們暫且稱它為4D ALU。需要注意的是,4D SIMD架構雖然很適合處理4D指令,但遇到1D指令的時候效率便會降為原來的1/4。此時ALU 3/4的資源都被閒置。為了提高PS VS執行1D 2D 3D指令時的資源利用率,DirectX9時代的GPU通常採用1D+3D或2D+2D ALU。這便是Co-issue技術。這種ALU對4D指令的計算時仍然效能與傳統的ALU相同,但當遇到1D 2D 3D指令時效率則會高不少,例如如下指令:ADD R0.xyz , R0,R1 //此指令是將R0,R1向量的x,y,z值相加 結果賦值給R0ADD R3.x , R2,R3 //此指令是將R2 R3向量的w值相加 結果賦值給R3對於傳統的4D ALU,顯然需要兩個週期才能完成,第一個週期ALU利用率75% ,第二個週期利用率25%。而對於1D+3D的ALU,這兩條指令可以融合為一條4D指令,因而只需要一個週期便可以完成,ALU利用率100%。但當然,即使採用co-issue,ALU利用率也不可能總達到100%,這涉及到指令並行的相關性等問題,而且,更直觀的,上述兩條指令顯然不能被2D+2D ALU一週期完成,而且同樣,兩條2D指令也不能被1D+3D ALU一週期完成。傳統GPU在對非4D指令的處理顯然不是很靈活。總結:傳統的GPU中定點和畫素處理分別由VS和PS來完成,每個VS PS單元中通常有一個4D ALU,可以在一個週期完成4D向量操作,但這種ALU對1D 2D 3D操作效率低下,為了彌補,DX9顯示卡中ALU常被設定為1D+3D 2D+2D等形式。第五章:統一渲染架構相對於DirectX 9來說,最新的DirectX 10最大的改進在於提出了統一渲染架構,即Unified Shader。傳統的顯示卡GPU一直採用分離式架構,頂點處理和畫素處理分別由Vertex Shader和Pixel Shader來完成,於是,當GPU核心設計完成時,PS和VS的數量便確定下來了。但是不同的遊戲對於兩者處理量需求是不同的,這種固定比例的PS VS設計顯然不夠靈活,為了解決這個問題,DirectX10規範中提出了了統一渲染架構。不論是頂點資料還是畫素資料,他們在計算上都有很多共同點,例如通常情況下,他們都是4D向量,而且在ALU中的計算都是沒有分別的浮點運算。這些為統一渲染的實現提供了可能。在統一渲染架構中,PS單元和VS單元都被通用的US單元所取代,nVidia的實現中稱其為streaming processer,即流處理器,這種US單元既可以處理頂點資料,又可以處理畫素資料,因而GPU可以根據實際處理需求進行靈活的分配,這樣便有效避免了傳統分離式架構中VS和PS工作量不均的情況。總結:統一渲染架構使用US(通常為SP)單元取代了傳統的固定數目的VS和PS單元,US既可以完成頂點操作,又可以完成畫素操作,因而可以根據遊戲需要靈活分配,從而提高了資源利用率。第六章:G80和R600的統一渲染架構實現以下我們著重討論G80和R600的統一著色單元而不考慮紋理單元,ROP等因素。G80 GPU中安排了16組共128個統一標量著色器,被叫做stream processors,後面我們將其簡稱為SP。每個SP都包含有一個全功能的1D ALU。該ALU可以在一週期內完成乘加操作(MADD)。也許有人已經注意到了,在前面傳統GPU中VS和PS的ALU都是4D的,但在這裡,每個SP中的ALU都是1D標量ALU。沒錯,這就是很多資料中提及的MIMD(多指令多資料)架構,G80走的是徹底的標量化路線,將ALU拆分為了最基本的1D 標量ALU,並實現了128個1D標量SP,於是,傳統GPU中一個週期完成的4D向量操作,在這種標量SP中需4個週期才能完成,或者說,1個4D操作需要4個SP並行處理完成。這種實現的最大好處是靈活,不論是1D,2D,3D,4D指令,G80得便宜其全部將其拆成1D指令來處理。指令其實與向量運算拆分一樣。例如一個4D向量指令 ADD R0.xyzw , R0,R1 R0與R1向量相加,結果賦R0G80的編譯器會將其拆分為4個1D標量運算指令並將其分派給4個SP:ADD R0.x , R0,R1 ADD R0.y , R0,R1 ADD R0.z , R0,R1ADD R0.w, R0,R1綜上:G80的架構可以用128X1D來描述。R600的實現方式則與G80有很大的不同,它仍然採用SIMD架構。在R600的核心裡,共設計了4組共64個流處理器,但每個處理器中擁有1個5D ALU,其實更加準確地說,應該是5個1D ALU。因為每個流處理器中的ALU可以任意以1+1+1+1+1或1+4或2+3等方式搭配(以往的GPU往往只能是1D+3D或2D+2D)。ATI將這些ALU稱作streaming processing unit,因而,ATI宣稱R600擁有320個SPU。我們考慮R600的每個流處理器,它每個週期只能執行一條指令,但是流處理器中卻擁有5個1D ALU。ATI為了提高ALU利用率,採用了VLIW體系(Very Large Instruction Word)設計。將多個短指令合併成為一組長的指令交給流處理器去執行。例如,R600可以5條1D指令合併為一組5DVLIW指令。對於下述指令:ADD R0.xyz , R0,R1 //3DADD R4.x , R4,R5 //1DADD R2.x , R2,R3 //1DR600也可以將其整合為一條VL
第一章:第二代及以後的GPU工作流程簡介簡單(而不一定絕對科學)的說:GPU主要完成對3D圖形的處理--圖形的生成渲染。GPU的圖形(處理)流水線完成如下的工作:(並不一定是按照如下順序)頂點處理:這階段GPU讀取描述3D圖形外觀的頂點資料並根據頂點資料確定3D圖形的形狀及位置關係,建立起3D圖形的骨架。在支援DX8和DX9規格的GPU中,這些工作由硬體實現的Vertex Shader(定點著色器)完成。光柵化計算:顯示器實際顯示的影象是由畫素組成的,我們需要將上面生成的圖形上的點和線透過一定的演算法轉換到相應的畫素點。把一個向量圖形轉換為一系列畫素點的過程就稱為光柵化。例如,一條數學表示的斜線段,最終被轉化成階梯狀的連續畫素點。紋理帖圖:頂點單元生成的多邊形只構成了3D物體的輪廓,而紋理對映(texture mapping)工作完成對多變形表面的帖圖,通俗的說,就是將多邊形的表面貼上相應的圖片,從而生成“真實”的圖形。TMU(Texture mapping unit)即是用來完成此項工作。 畫素處理:這階段(在對每個畫素進行光柵化處理期間)GPU完成對畫素的計算和處理,從而確定每個畫素的最終屬性。在支援DX8和DX9規格的GPU中,這些工作由硬體實現的Pixel Shader(畫素著色器)完成。最終輸出:由ROP(光柵化引擎)最終完成畫素的輸出,1幀渲染完畢後,被送到視訊記憶體幀緩衝區。總結:GPU的工作通俗的來說就是完成3D圖形的生成,將圖形對映到相應的畫素點上,對每個畫素進行計算確定最終顏色並完成輸出。第二章:DirectX8和DirectX9 GPU的傳統流水線前面的工作流程其實已經說明了問題。本章來總結一下,承前啟後。傳統的GPU功能部件我們不妨將其分為頂點單元和畫素流水線兩部分。頂點單元由數個硬體實現的Vertex Shader組成。傳統的畫素流水線由幾組PSU(Pixel Shader Unit)+TMU+ROP組成。於是,傳統的GPU由頂點單元生成多邊形,並由畫素流水線負責畫素渲染和輸出。對於畫素流水線需要做的說明是:雖然傳統的流水線被認為=1PSU+1TMU+1ROP,但這個比例不是恆定的,例如在RadeonX1000(不包括X1800)系列中被廣為稱道的3:1黃金架構,PSU:TMU:ROP的數量為3:1:1。一塊典型的X1900顯示卡具有48個PSU,16個TMU和16個ROP。之所以採用這種設計方法,主要考慮到在當今的遊戲中,畫素指令數要遠遠大於紋理指令的數量。ATI憑藉這個優秀的架構,成功擊敗了Geforce7,在DX9後期取得了3D效能上的領先。總結:傳統的GPU由頂點單元生成多邊形,畫素流水線渲染畫素並輸出,一條畫素流水線包含PSU,TMU,和ROP(有的資料中不包含ROP),比例通常為1:1:1,但不固定。第三章:頂點和畫素操作指令GPU透過執行相應的指令來完成對頂點和畫素的操作。熟悉OpenGL或Direct3D程式設計的人應該知道,畫素通常使用RGB三原色和alpha值共4個通道(屬性)來描述。而對於頂點,也通常使用XYZ和W 4個通道(屬性)來描述。因而,通常執行一條頂點和畫素指令需要完成4次計算,我們這裡成這種指令為4D向量指令(4維)。當然,並不是所有的指令都是4D指令,在實際處理中,還會出現大量的1D標量指令以及2D,3D指令。總結:由於定點和畫素通常用4元組表示屬性,因而頂點和畫素操作通常是4D向量操作,但也存在標量操作。第四章:傳統GPU指令的執行傳統的GPU基於SIMD的架構。SIMD即Single Instruction Multiple Data,單指令多資料。其實這很好理解,傳統的VS和PS中的ALU(算術邏輯單元,通常每個VS或PS中都會有一個ALU,但這不是一定的,例如G70和R5XX有兩個)都能夠在一個週期內(即同時)完成對向量4個通道的運算。比如執行一條4D指令,PS或VS中的ALU對指令對應定點和畫素的4個屬性資料都進行了相應的計算。這便是SIMD的由來。這種ALU我們暫且稱它為4D ALU。需要注意的是,4D SIMD架構雖然很適合處理4D指令,但遇到1D指令的時候效率便會降為原來的1/4。此時ALU 3/4的資源都被閒置。為了提高PS VS執行1D 2D 3D指令時的資源利用率,DirectX9時代的GPU通常採用1D+3D或2D+2D ALU。這便是Co-issue技術。這種ALU對4D指令的計算時仍然效能與傳統的ALU相同,但當遇到1D 2D 3D指令時效率則會高不少,例如如下指令:ADD R0.xyz , R0,R1 //此指令是將R0,R1向量的x,y,z值相加 結果賦值給R0ADD R3.x , R2,R3 //此指令是將R2 R3向量的w值相加 結果賦值給R3對於傳統的4D ALU,顯然需要兩個週期才能完成,第一個週期ALU利用率75% ,第二個週期利用率25%。而對於1D+3D的ALU,這兩條指令可以融合為一條4D指令,因而只需要一個週期便可以完成,ALU利用率100%。但當然,即使採用co-issue,ALU利用率也不可能總達到100%,這涉及到指令並行的相關性等問題,而且,更直觀的,上述兩條指令顯然不能被2D+2D ALU一週期完成,而且同樣,兩條2D指令也不能被1D+3D ALU一週期完成。傳統GPU在對非4D指令的處理顯然不是很靈活。總結:傳統的GPU中定點和畫素處理分別由VS和PS來完成,每個VS PS單元中通常有一個4D ALU,可以在一個週期完成4D向量操作,但這種ALU對1D 2D 3D操作效率低下,為了彌補,DX9顯示卡中ALU常被設定為1D+3D 2D+2D等形式。第五章:統一渲染架構相對於DirectX 9來說,最新的DirectX 10最大的改進在於提出了統一渲染架構,即Unified Shader。傳統的顯示卡GPU一直採用分離式架構,頂點處理和畫素處理分別由Vertex Shader和Pixel Shader來完成,於是,當GPU核心設計完成時,PS和VS的數量便確定下來了。但是不同的遊戲對於兩者處理量需求是不同的,這種固定比例的PS VS設計顯然不夠靈活,為了解決這個問題,DirectX10規範中提出了了統一渲染架構。不論是頂點資料還是畫素資料,他們在計算上都有很多共同點,例如通常情況下,他們都是4D向量,而且在ALU中的計算都是沒有分別的浮點運算。這些為統一渲染的實現提供了可能。在統一渲染架構中,PS單元和VS單元都被通用的US單元所取代,nVidia的實現中稱其為streaming processer,即流處理器,這種US單元既可以處理頂點資料,又可以處理畫素資料,因而GPU可以根據實際處理需求進行靈活的分配,這樣便有效避免了傳統分離式架構中VS和PS工作量不均的情況。總結:統一渲染架構使用US(通常為SP)單元取代了傳統的固定數目的VS和PS單元,US既可以完成頂點操作,又可以完成畫素操作,因而可以根據遊戲需要靈活分配,從而提高了資源利用率。第六章:G80和R600的統一渲染架構實現以下我們著重討論G80和R600的統一著色單元而不考慮紋理單元,ROP等因素。G80 GPU中安排了16組共128個統一標量著色器,被叫做stream processors,後面我們將其簡稱為SP。每個SP都包含有一個全功能的1D ALU。該ALU可以在一週期內完成乘加操作(MADD)。也許有人已經注意到了,在前面傳統GPU中VS和PS的ALU都是4D的,但在這裡,每個SP中的ALU都是1D標量ALU。沒錯,這就是很多資料中提及的MIMD(多指令多資料)架構,G80走的是徹底的標量化路線,將ALU拆分為了最基本的1D 標量ALU,並實現了128個1D標量SP,於是,傳統GPU中一個週期完成的4D向量操作,在這種標量SP中需4個週期才能完成,或者說,1個4D操作需要4個SP並行處理完成。這種實現的最大好處是靈活,不論是1D,2D,3D,4D指令,G80得便宜其全部將其拆成1D指令來處理。指令其實與向量運算拆分一樣。例如一個4D向量指令 ADD R0.xyzw , R0,R1 R0與R1向量相加,結果賦R0G80的編譯器會將其拆分為4個1D標量運算指令並將其分派給4個SP:ADD R0.x , R0,R1 ADD R0.y , R0,R1 ADD R0.z , R0,R1ADD R0.w, R0,R1綜上:G80的架構可以用128X1D來描述。R600的實現方式則與G80有很大的不同,它仍然採用SIMD架構。在R600的核心裡,共設計了4組共64個流處理器,但每個處理器中擁有1個5D ALU,其實更加準確地說,應該是5個1D ALU。因為每個流處理器中的ALU可以任意以1+1+1+1+1或1+4或2+3等方式搭配(以往的GPU往往只能是1D+3D或2D+2D)。ATI將這些ALU稱作streaming processing unit,因而,ATI宣稱R600擁有320個SPU。我們考慮R600的每個流處理器,它每個週期只能執行一條指令,但是流處理器中卻擁有5個1D ALU。ATI為了提高ALU利用率,採用了VLIW體系(Very Large Instruction Word)設計。將多個短指令合併成為一組長的指令交給流處理器去執行。例如,R600可以5條1D指令合併為一組5DVLIW指令。對於下述指令:ADD R0.xyz , R0,R1 //3DADD R4.x , R4,R5 //1DADD R2.x , R2,R3 //1DR600也可以將其整合為一條VL