想了解GPU硬件相關(guān)知識,網(wǎng)上內(nèi)容太雜亂,而且網(wǎng)上關(guān)于RTR4圖形硬件部分的翻譯機翻味道太重了,看得莫名其妙,所以在學(xué)的同時順手翻譯了.個人渣翻,有錯誤還請指出.
圖形硬件
23.1 光柵化
光柵化包括三角形裝配和三角形遍歷,此外,我們還將介紹如何在一個三角形中插值,三角形中插值與三角形遍歷聯(lián)系緊密.
每個像素中心的坐標(biāo)是,x與y都是整數(shù),
是屏幕的分辨率.三角形中,未經(jīng)過變換的頂點為
,經(jīng)過MVP變換后但沒有除w分量的坐標(biāo)為
.投射到屏幕空間中后的坐標(biāo)為
.
在著色過程中,一個像素網(wǎng)格被劃分為2*2的組合,稱之為Quad,當(dāng)一個Quad中有一個像素被包含進(jìn)三角形內(nèi)部,此Quad中的其余像素都被稱作輔助像素,這樣的設(shè)計在著色過程中便于計算細(xì)節(jié)的紋理等級(,這是大多數(shù)GPU設(shè)計的核心并且影響后續(xù)階段).輔助像素是在片元著色的過程中用來計算有限差分的,使用貼圖LOD時需要計算UV差分值.Quad的設(shè)計導(dǎo)致越小的三角形,邊際輔助像素的開銷越大,造成一定的性能浪費.輔助像素的數(shù)量也叫做Quad overshading.
硬件通過對三角形的每一邊計算邊緣函數(shù)來決定是否一個像素的中心(或其他采樣點)處于三角形中.
是邊的法向量,
是邊上的點.我們可以通過邊的兩個頂點
和
來得到邊的向量
,法向量就是把邊向量逆時針旋轉(zhuǎn)90度得到.
對于計算結(jié)果,像素恰好在三角形邊上;若
,稱為該像素在正向的半邊,即在三角形內(nèi)部的一側(cè);若
,該像素就在三角形外部的一側(cè).這可以判斷一個像素是否在三角形內(nèi)部,如果一個像素在三角形內(nèi)或邊上,那該像素必須滿足對每一條邊都
.
圖形API會要求計算屏幕空間的浮點數(shù)頂點坐標(biāo),并把它轉(zhuǎn)換為定點數(shù)坐標(biāo),這是為了定義tie-breaker規(guī)則.同時,這種設(shè)計也可以更高效地判斷三角形內(nèi).浮點數(shù)坐標(biāo)轉(zhuǎn)換為定點數(shù)坐標(biāo)的轉(zhuǎn)換過程會在邊緣函數(shù)計算前就完成了.比如使用(1,14,8)的格式定義定點數(shù),1位表示正負(fù),14位表示整數(shù)坐標(biāo),8位表示在像素內(nèi)部的小數(shù)坐標(biāo).對于一個坐標(biāo),整數(shù)坐標(biāo)處于
范圍內(nèi),而像素點內(nèi)部有
種可能位置.
邊緣函數(shù)的另一個重要性質(zhì)是可加性(incremental),當(dāng)一個像素中心點計算完畢
后,可以很方便地計算出
.這個方法經(jīng)常被用作計算小片的像素是否在區(qū)域內(nèi),對于一小塊像素,會使用每個像素對應(yīng)1bit的掩碼來記錄它是否在區(qū)域內(nèi).
兩個三角形共用一條邊,同時這一條邊穿過了一個像素的中心,出于效率角度考慮,那么這個像素會被一個三角形包含,然后被另一個三角形覆蓋.為了達(dá)到這個目的,我們需要用到tie-breaker規(guī)則.這里介紹在Dx12中應(yīng)用的top-left規(guī)則.對于三角形三條邊的邊緣函數(shù)而言,均成立,則代表該像素在三角形中,top-left規(guī)則應(yīng)用于三角形邊穿過像素的情況.三角形的頂邊(top edge)指其他邊在其下方并且水平的邊;三角形的左邊(left edge)指在三角形左側(cè)并且非水平的邊,這也意味著左邊至多可以有兩條.用邊緣函數(shù)的參數(shù)來表示就是,頂邊的條件是
且
, 左邊的條件是
.測試采樣點
在不在三角形內(nèi)部的測試叫做內(nèi)部測試(inside test).
一條直線在渲染時會當(dāng)作一個一像素寬的長方形處理,能夠由兩個三角形組成,同時也能多用一次額外的邊緣方程.這種設(shè)計方法的優(yōu)點是使直線也能夠應(yīng)用邊緣方程.點會被當(dāng)作四變形來繪制.
為了提高效率,通常以分層的方式進(jìn)行三角形遍歷.通常硬件會計算屏幕空間內(nèi)點的包圍盒子,并確定哪個片(tile)在包圍盒中并且與三角形重合.確定一個片是否在包圍盒外的方式是二維版的AABB平面測試.處理方法如圖所示:在遍歷開始前,首先確定該片的哪個角點參與測試,對于每個參與測試的片來說,對一條特定的邊,參與測試的角點的位置是相同的,因為哪個角點距離邊更近只取決于邊的法線.選出的角點會參與邊緣函數(shù)的測試,當(dāng)角點在邊緣以外,也就說明該角點所在的片在邊緣以外,硬件不會再測試這個片中的其他像素了.相鄰的片的測試也會應(yīng)用可加性質(zhì),舉例來說,水平向右距離8個像素的點,只需在上一個邊緣函數(shù)結(jié)果上加.
經(jīng)歷過二維的片/邊緣測試后,現(xiàn)在需要分層遍歷三角形了.方法如圖所示.遍歷片也需要用某種順序,一般采用之字形遍歷或其他的空間填充曲線(space filling curve),可以增加相干性.如果需要,在層次遍歷中也是可以添加其他的層級的.例如層級遍歷時,可以先按16*16的片大小遍歷測試,有與三角形重合的部分后,遍歷測試4*4的片大小層級.
片平鋪遍歷的主要優(yōu)勢在于(比如)以掃描線順序遍歷三角形加矛,像素的處理方式更加連貫蔫浆,因此井佑,紋理的訪問也更加連貫.同時在處理顏色和深度緩沖時具有局部的優(yōu)勢.按掃描線的方式遍歷能夠緩存最近用到的紋素顏色方便復(fù)用.當(dāng)使用圖像金字塔進(jìn)行紋理采樣時會增加緩存中的紋素復(fù)用層級,但是如果對像素進(jìn)行掃描線的方式遍歷,當(dāng)掃描到最后的紋素顏色時,最初緩存的紋素顏色緩存很可能已經(jīng)被釋放.因為緩存比反復(fù)從內(nèi)存中讀取更有效率,所以三角形通常以片的形式遍歷.這種方式會對紋理采樣,深度緩沖和顏色緩沖更有利.事實上,紋理緩沖,深度緩沖和顏色緩沖也通過片的方式存儲.
在三角形遍歷開始前,GPU通常會進(jìn)行三角形裝配.這個步驟是為了計算三角形的常數(shù)參數(shù),方便后續(xù)進(jìn)行遍歷.三角形裝配也會對屬性插值相關(guān)的常數(shù)參數(shù)進(jìn)行計算.在后續(xù)我們還會發(fā)現(xiàn)其他需要在三角形裝配環(huán)節(jié)進(jìn)行計算的常數(shù).
裁剪過程是在三角形裝配前完成的,因為裁剪會產(chǎn)生更多的三角形.將三角形裁剪出觀察空間是巨大開銷的過程,所以GPU不在萬不得以的情況下不會進(jìn)行裁剪.我們通常需要將三角形裁剪出近平面,這個過程會額外生成一個或兩個三角形.對于屏幕上的邊來說,GPU使用guard-band clipping來減少裁剪的次數(shù).這個裁剪方法如圖所示.
23.1.1 插值
重心坐標(biāo)是計算光線與三角形相交的副產(chǎn)品,任何頂點的參數(shù)
,都能通過重心坐標(biāo)插值的方式求出
在公式中,是插值參數(shù)
在三角形中插值得到.重心坐標(biāo)的定義是:
是該插值點連接三角形頂點構(gòu)成的子三角形的面積,具體見圖所示.重心坐標(biāo)還有一個分量
,由于
,這里
由
代替.
邊緣方程可以寫做邊的法線的形式 ,其中
,這種形式的邊緣方程也可以寫作
,
是邊
的長度,
就是邊
逆時針旋轉(zhuǎn)90度得到的.(原因:邊緣函數(shù)中的法線既可以取歸一化后的法線,也可以不歸一化,不影響最終結(jié)果,在這里取的
就是未歸一化的法線.).公式中的
項是線段
在
上的投影,也就是
到
的高
.也就是說,
,可以順便求出
的大小,因為我們需要
來計算重心坐標(biāo).
在三角形裝配過程中會計算因為三角形的面積不變,這樣也避免了對像素分割.當(dāng)我們對三角形進(jìn)行邊緣遍歷時,我們能夠順便得到上式子的所有項,這在插值深度和正交投影時是準(zhǔn)確的,但在處理透視投影時,重心坐標(biāo)插值處理紋理會出現(xiàn)偏差.下圖解釋了.
透視校正重心坐標(biāo)對每個像素做了一些除法操作.因為線性插值開銷小,我們也知道如何計算,我們應(yīng)當(dāng)盡可能多地在屏幕空間應(yīng)用線性插值,在透視校正中也是如此.在三角形中線性插值
和
,其中
是頂點經(jīng)過一系列變換后的第四維坐標(biāo)分量.把
和
相除,其比值依舊是
.這就是逐頂點的除法.(也就是為什么投影變換以后要逐頂點除w,因為要做透視校正)例子:直線上點坐標(biāo)為
,有兩個點
和
,求這兩個點的中點的插值坐標(biāo).1.插值
和
:
即4和2,中點插值為3;
即1和1/3,中點插值為2/3. 2.計算
:即3/(2/3),a=4.5. 所以
和
的插值中點為4.5
實際應(yīng)用中,通常需要利用透視校正來插值許多參數(shù),所以需要計算透視校正重心坐標(biāo)來輔助插值.所以我們需要對
作出一些修改:
因為,三角形裝配過程能夠計算并存儲
和
和
來使逐像素的計算更快.相對來說,所有f方程都能乘上
,所以我們存儲
,
和
.經(jīng)過投影校正的重心坐標(biāo)就是:
投影校正重心坐標(biāo)我們需要每個像素計算一次,就可以插值計算任何需要投影校正后的參數(shù).需要注意與不同,
與子三角形面積不成比例,另外分母不是常數(shù),這也要求了必須每像素執(zhí)行一次.
最后,關(guān)于深度應(yīng)該使用
計算每個頂點的深度然后使用(u,v)進(jìn)行線性插值.這種方式有好處比如壓縮深度緩沖.
23.1.2 保守光柵化
DX11和OpenGL的拓展中,定義了一種新的三角形遍歷方式,保守光柵化(conservative rasterization(CR)).保守光柵化分為兩種,高估保守光柵化(overestimated conservative rasterization, OCR)和低估保守光柵化(underestimated conservative rasterization,UCR).也被稱作外部保守光柵化(outer-conservative rasterization)和內(nèi)部保守光柵化(inner-conservative rasterization).如圖所示.
OCR是三角形只要與像素有相交就包含該像素,而UCR是完全在三角形中的像素才被包含.OCR和UCR都可以通過將片大小縮小到一個像素來使用片遍歷來實現(xiàn).當(dāng)硬件中沒有支持時笤成,可以使用幾何體著色器或三角形擴展實現(xiàn)OCR.CR可用于圖像空間中的碰撞檢測、遮擋剔除誊爹、陰影計算和抗鋸齒等算法仍秤。
最后,所有的光柵化操作都是在幾何處理和像素片元處理之間的橋梁過程.為了計算最終的三角形頂點位置和最終的像素顏色,GPU接下來需要進(jìn)行海量的彈性運算.
23.2 海量運算和調(diào)度
為了提供巨量的對于任意計算任務(wù)的計算力,大多數(shù)GPU架構(gòu)都采用統(tǒng)一的著色器架構(gòu),采用SIMD多線程處理(single instruction multiple data,單指令多數(shù)據(jù)流),也稱做SIMT處理或超線程.(看3.10了解SIMD處理).warp是英偉達(dá)的概念,AMD硬件中稱為waves或wavefronts.接下來我們會首先介紹GPU中典型的統(tǒng)一的算數(shù)邏輯單元.(arithmetic logic unit,ALU)
ALU,也叫做SIMD lane是硬件的一部分用于在一整個上下文中計算一段整體的程序,如頂點或片元著色器.典型的ALU結(jié)構(gòu)如圖所示,主要的計算單元是一個浮點計算單元(FP unit)和一個整數(shù)計算單元(int unit).浮點單元采用IEEE 754浮點數(shù)標(biāo)準(zhǔn)并支持fused-multiply and add(FMA)指令作為其支持的最復(fù)雜的指令之一.一個ALU還包含move/compare和load/store,分支判斷和超越數(shù)計算(正余弦和指數(shù)).因為超越數(shù)單元不常用,這些單元可能被組合起來放在特殊單元中(special unit,SU),這些單元可能分別位于不同的硬件單元結(jié)構(gòu)中,例如一些超越數(shù)計算硬件單元可能為更多的ALU服務(wù).ALU結(jié)構(gòu)通常使用管線并行,例如,當(dāng)一些指令計算乘法時,下一個指令也正在執(zhí)行取值操作.顯而易見,在理想情況下,管線階段劃分越細(xì),整體操作的執(zhí)行也就越快.ALU采用流水線結(jié)構(gòu)還有一個原因是,一個流水線中,運行最慢的硬件部分決定了整體執(zhí)行的最大時鐘頻率,所以細(xì)分流水線上塊的數(shù)量可以使整體執(zhí)行更加迅速.但是為了簡化ALU的設(shè)計,ALU通常只有幾個流水線階段.
ALU不同于CPU的一點是,ALU沒有許多附加功能,如分支預(yù)測,寄存器重命名,深度指令管線等.GPU在芯片中,使用大量重復(fù)的ALU來提供巨大的算力,擴大寄存器大小以方便warp切換.例如GTX1080Ti有3584個ALU.為了方便調(diào)度GPU任務(wù),大多數(shù)GPU將ALU32個一組時鐘來同步運行,將這一組ALU稱作SIMD引擎.不同的廠商對ALU組稱呼不同,我們使用多處理器(multiprocessor,MP)來稱呼.例如英偉達(dá)叫流多處理器,英特爾叫執(zhí)行單元(execution unit),AMD叫計算單元(compute unit).MP示例如圖所示.每個MP通常由個調(diào)度器來為SIMD引擎分配任務(wù),MP中還會有L1緩存,局部數(shù)據(jù)存儲(local data storage,LDS),紋理單元(texture unit,TX)和特殊單元(SU)來處理ALU無法處理的任務(wù).調(diào)度器會以SIMD多線程的方式為ALU分配任務(wù).MP的架構(gòu)不同的廠商不同.
因為圖形任務(wù)中有眾多相同計算的任務(wù),如頂點和片元著色器執(zhí)行相同的程序,這種特點決定了GPU使用SIMD處理過程.這種結(jié)構(gòu)被稱為線程級并行(thread-level paralleism)也就是指頂點和片元著色器執(zhí)行過程中與其他頂點和片元相獨立.也就是說,對于采用SIMD或SIMT處理的任務(wù),一個任務(wù)被SIMD引擎的所有l(wèi)ane所同時執(zhí)行.指令級并行(instruction-level paralleism)指如果處理器能夠?qū)⒅噶顒澐殖杀舜霜毩⒌牟糠?這些指令也能同時并行執(zhí)行,因為存在可以并行的資源.
靠近MP的位置是調(diào)度器(warp scheduler),它接收需要被MP執(zhí)行的大量任務(wù).調(diào)度器的作用就是將工作以warp的形式分配給MP,將寄存器文件(register file,RF)中的寄存器分配給warp中的線程,然后以最佳的方式對任務(wù)進(jìn)行優(yōu)先級排序.通常下游工作優(yōu)先級高于上游工作,如片元著色器有限級高于頂點著色器,這樣可以避免堵塞.MP可以處理成百上千個線程來避免內(nèi)存訪問的延遲.調(diào)度器可以立刻從一個正在運行的warp切換為準(zhǔn)備執(zhí)行的warp,因為調(diào)度器是由專用硬件開發(fā)的,所以可以零開銷地切換warp.例如,如果當(dāng)前warp執(zhí)行一個紋理加載指令临燃,紋理加載指令預(yù)計會有較長的延遲,調(diào)度器可以立即切換當(dāng)前warp烙心,用另一個替換它膜廊,并繼續(xù)執(zhí)行該warp.這樣,計算單位得到了更好的利用.
對于片元著色任務(wù),warp調(diào)度器會分發(fā)幾個完整的Quad,因為會計算UV微分,像素都是以Quad的尺度著色(在23.8還會提到).所以如果一個warp的大小是32,那么32/4=8個Quad會被調(diào)度器分配執(zhí)行.這里涉及到一個架構(gòu)選擇問題,有的架構(gòu)會鎖定一整個warp在一個三角形中,有的架構(gòu)會讓不同的Quad在不同的三角形中(一個warp不一個三角形).對于前者很容易實現(xiàn)但是對于小三角形而言會浪費效率(一個warp一個小三角形).后者對于小三角形更加友好.
總體來說,為了更高的計算密度,MP還會打包成Chip,并且GPU也會有更高等級的調(diào)度器.更高級的調(diào)度器負(fù)責(zé)把任務(wù)按需要提交給GPU的結(jié)果為依據(jù),劃分分發(fā)給warp調(diào)度器.在一個warp中有多個線程也意味著該線程中的任務(wù)需要和其他線程保持獨立,圖形處理過程中通常都是這樣的.例如對一個頂點著色和片元著色一般也不和其他頂點和片元相關(guān).
現(xiàn)在我們已經(jīng)了解光柵化和ALU相關(guān),接下來還會介紹內(nèi)存系統(tǒng),緩存,紋理.緊接著要介紹的是延遲和占用.
23.3 延遲和占用
延遲是查詢發(fā)出后到返回結(jié)果的這段時間.例如根據(jù)地址尋址取值的操作,延遲就是尋址開始到獲取內(nèi)容的時間.從一個紋理單元訪問一個紋理值的時間可能需要花費幾百甚至幾千個時鐘周期(GPU中訪問內(nèi)存數(shù)據(jù)和貼圖是很慢的).所以在實際應(yīng)用中,GPU要盡量隱藏這部分延遲,否則GPU任務(wù)執(zhí)行時間就會被內(nèi)存訪問的時間占據(jù).
一個隱藏延遲的方法就是SIMD處理的多線程過程,也就是23.2中提到的warp調(diào)度和切換.MP能處理的warps的最大數(shù)量是有限的,活躍的warp數(shù)量取決于寄存器使用和紋理采樣器,L1緩存,插值器和其他因素.這里我們定義占用率(occupancy,):
是一個MP中可以處理的warp數(shù)量最大值,
是當(dāng)前正在使用的warp數(shù)量.
是衡量計算資源投入使用的效率的量.計算舉例:假設(shè)
,一個著色器處理器有256kB的寄存器大小,一個著色器程序線程使用27個32位浮點數(shù)寄存器,一個著色器程序線程使用150個32位浮點數(shù)寄存器,SIMD寬度是32,我們?yōu)檫@兩個著色器程序分別計算活躍warp數(shù)量:
(著色器處理器的寄存器總大小/著色器程序總使用的寄存器大小)在第一種情況里,較小的著色器程序占用了27個寄存器,
,所以占用率就是1,這是較好的情況,因為能夠較好的隱藏延遲.對于第二種情況,
,這占用率比較低,會影響到延遲的隱藏.所以要設(shè)計出能夠更好地平衡最大warp,寄存器大小和其他共享資源的架構(gòu).
有時,過高的占用率可能會適得其反淫茵,因為如果著色器占用過多內(nèi)存訪問爪瓜,則可能會打亂緩存,導(dǎo)致緩存失效,讓執(zhí)行更慢了.另一種延遲隱藏機制是在內(nèi)存請求之后繼續(xù)執(zhí)行同一warp,如果有獨立于內(nèi)存訪問結(jié)果的指令匙瘪,就繼續(xù)執(zhí)行(在同一warp中異步執(zhí)行以隱藏延遲).程序使用了更多的寄存器,有時就會獲得更低的占用率.一個例子是循環(huán)展開铆铆,它為指令級并行提供了更多的可能性蝶缀,因為通常會生成更長的獨立指令鏈,這使得在切換之前執(zhí)行更長時間成為可能薄货。然而這種方式也會占用更多臨時寄存器.一般的原則是追求更高的占用率,過低的占用率意味著當(dāng)一個著色器請求訪問紋理時,切換到其他warp更困難.
另一種延遲的原因是GPU和CPU之間的數(shù)據(jù)通信.把GPU和CPU想象成兩個分離的計算機異步地工作,這使得二者之間的通信比較耗費時間.轉(zhuǎn)換二者的信息流向產(chǎn)生的延遲非常影響效率.當(dāng)從GPU中讀取數(shù)據(jù)時,GPU流水線必須被flush,在這段時間,CPU都在等待GPU完成工作.在一些架構(gòu)中,如英特爾的GEN,GPU和CPU集成在同一芯片上,并且共享了相同的內(nèi)存模型,低級的緩存被共享,高級的緩存不共享,這樣延遲就被大大縮減了.
不會產(chǎn)生CPU stall的回讀機制(read-back,GPU向CPU傳遞數(shù)據(jù))的一個示例是遮擋查詢.對于遮擋測試,機制是執(zhí)行查詢,然后偶爾檢查GPU看看查詢的結(jié)果是否可用.在等待結(jié)果的同時翁都,CPU和GPU還可以完成其他的工作.
23.4 內(nèi)存架構(gòu)和總線
端口(port)是在兩個設(shè)備間負(fù)責(zé)發(fā)送數(shù)據(jù)的通道,總線(bus)是在兩個以上的設(shè)備間發(fā)送共享數(shù)據(jù)的通道.帶寬(bandwidth)是用來描述在端口和總線中發(fā)送總信息量的量,單位是字節(jié)/秒(B/s).端口和總線在計算機圖形學(xué)中重要的概念因為它們起著將各部分連接起來的作用.帶寬也是個重要的資源,所以需要在搭建一個圖形系統(tǒng)時精細(xì)地設(shè)計和分析帶寬.因為端口和總線同時提供了數(shù)據(jù)傳遞的功能,說端口的時候也經(jīng)常指的是總線.
對于許多GPU來說,在GPU上擁有獨立的GPU內(nèi)存(顯存)非常常見,顯存也經(jīng)常被稱為視頻內(nèi)存(video memory).訪問顯存要比讓GPU通過總線訪問系統(tǒng)內(nèi)存快得多.比如PC上的16位PCIe v3總線速度是15.75GB/s,PCIe v4總線速度是31.51GB/s.而Pascal架構(gòu)的GPU(GTX1080)的顯存訪問速度是320GB/s.
傳統(tǒng)上,顯存存儲的是紋理和渲染對象,但是其他數(shù)據(jù)也可以存儲在顯存中.在一個畫面中的許多物體不需要明顯地在每幀之間都變換形狀.即使是一個人類角色也通常使用不變的網(wǎng)格(mesh)進(jìn)行渲染,每幀變化的是這些網(wǎng)格在關(guān)節(jié)處混合的頂點.對于這種數(shù)據(jù),單純依靠模型變換矩陣和頂點著色器程序驅(qū)動動畫,這種就通常使用靜態(tài)的頂點緩沖(vertex buffer)和內(nèi)部緩沖(inner buffer)是放在顯存中,這樣做可以使GPU訪問緩沖的速度更快.對于每幀需要經(jīng)過CPU計算更新的頂點位置,需要用動態(tài)頂點緩沖(dynamic vertex buffer)和內(nèi)部緩沖(inner buffer)位于系統(tǒng)內(nèi)存中,這些緩沖能夠通過總線訪問.PCI的一個很棒的特性是查詢是管線形式的,所以查詢總會在結(jié)果返回前完成.
大多數(shù)游戲機器,比如PS4和全部Xbox系列,使用的是統(tǒng)一內(nèi)存架構(gòu)(unified memory architecture,UMA),這意味著GPU能夠使用主機內(nèi)存的任意位置來存儲紋理和其他種類的緩沖.CPU和GPU使用相同的內(nèi)存和總線.這就明顯與專用的顯存有所區(qū)別.英特爾也使用UMA所以CPU與GEN9圖形架構(gòu)能使用同一內(nèi)存.如圖所示.但也不意味著所有緩存也都共享.圖形處理器擁有其獨占的L1,L2,L3緩存的部分,而LLC(last-level cache)才是共享的.對于任何計算機或圖形架構(gòu)而言,擁有一個緩存層次結(jié)構(gòu)是很重要的谅猾。如果訪問中存在某種局部性柄慰,那么這樣做可以減少對內(nèi)存的平均訪問時間。
23.5 緩存和壓縮
緩存在GPU中是在不同的位置分別存放的,存放的位置每個架構(gòu)都有不同,如圖所示.總體來說,GPU架構(gòu)增加緩存層級的目的是,通過應(yīng)用內(nèi)存訪問模式的局部性減少內(nèi)存延遲和帶寬占用.也就是說,GPU訪問了一個內(nèi)容,它很有可能接著訪問同樣的內(nèi)容或者其相鄰的內(nèi)容.大多數(shù)緩沖和紋理都是按照tiled模式存儲的,這也對增加局部性有幫助.假設(shè)緩存線由512bit(即64B)組成,并且當(dāng)前使用的顏色格式每像素4B.一種設(shè)計選擇是將所有像素存儲在64B中的一個4×4區(qū)域內(nèi),也稱為一個tile.也就是說,整個顏色緩沖區(qū)將被分割為4×4的tile.一個tile也可以跨越多個緩存線.
為了讓GPU架構(gòu)更加高效,需要在各個方面減少帶寬的占用.大多數(shù)GPU的硬件單元會將渲染目標(biāo)實時地壓縮和解壓.這些壓縮算法都是無損的,這樣可以完好地恢復(fù)回來.壓縮算法的核心就是我們稱之為tile table的結(jié)構(gòu),它存儲了每一個tile的額外信息.tile table會存儲在chip上或者級聯(lián)內(nèi)存中.如圖所示.總的來說,壓縮的方式在深度,顏色和模板是一樣的,有時會有一些改動.tile table中的每個元素都儲存了幀緩沖中tile內(nèi)部的像素狀態(tài).每個tile的狀態(tài)可能是壓縮的(compressed),解壓的(uncompressed)或者清除的(cleared).壓縮塊(compressed blocks)的壓縮的模式也有可能不同.例如,有壓縮至25%的也有壓縮至50%的.支持的壓縮等級取決于GPU能處理的內(nèi)存轉(zhuǎn)換(memory transfer)的尺寸大小.例如在某種架構(gòu)中,最小的內(nèi)存轉(zhuǎn)換大小是32B.如果tile size選擇為64B,那么它最大能被壓縮到50%(32B),而如果tile size為128B,那么它可以被壓縮到75%(96B),50%(64B)和25%(32B).
tile table經(jīng)常被應(yīng)用在快速清除render target.當(dāng)系統(tǒng)需要對render target進(jìn)行清除,tile table中的每個tile的狀態(tài)都被設(shè)置為已清除(cleared),但不涉及到緩沖區(qū)本身(tile table通過設(shè)置狀態(tài)就能實現(xiàn)快速clear).當(dāng)訪問渲染目標(biāo)的硬件單元需要讀取已清除的渲染目標(biāo)時,解壓縮單元首先檢查tile table中的狀態(tài),以查看tile是否已清除.如此,render target tile放進(jìn)緩存中時,會使用clear value而不需要讀取和解壓真實的render target數(shù)據(jù).通過這種方法,訪問render target在清除過程中把訪問成本縮小了,同時也節(jié)省了帶寬.如果tile table中的狀態(tài)不是cleared,那么就會讀取真實的render target,而且如果壓縮了,解壓縮器就會在發(fā)送數(shù)據(jù)之前解壓縮.
當(dāng)硬件單元訪問已經(jīng)寫入新值的render target時,當(dāng)tile從緩存中移出時,render target會被發(fā)送到壓縮單元并嘗試壓縮.如果壓縮單元支持兩種壓縮方式,那么兩種方式都會嘗試并應(yīng)用存儲占用小的那一個.因為API需要用無損的壓縮方式,所以如果所有壓縮方式都失敗,那么就會使用未壓縮的數(shù)據(jù).這也說明了無損的壓縮算法事實上也不是總能節(jié)省存儲空間的,但是是節(jié)省帶寬開銷的.如果壓縮成功,tile狀態(tài)就會設(shè)置為已壓縮(compressed),并以壓縮的格式發(fā)送數(shù)據(jù),反之則tile狀態(tài)設(shè)置為未壓縮(uncompressed).
需要注意的是,壓縮單元和解壓單元在緩沖前后都可以,如上圖所示.前緩沖壓縮(pre-cache)可以顯著增加緩沖的利用效率,但通常也會增加系統(tǒng)的復(fù)雜性.大多數(shù)顏色壓縮算法會對一個代表本tile的錨定值(anchor value)編碼,然后記錄其他像素值與錨定植的差并按其他方式編碼.對于深度值壓縮算法,因為深度在屏幕空間是線性的,所以大多數(shù)算法使用平面方程或差分方法得到.
使用標(biāo)準(zhǔn)深度(standard depth),即先進(jìn)行MVP變換再乘以透視除法得到的值,往往是不夠的.標(biāo)準(zhǔn)深度的主要問題是深度值不是線性的.大多數(shù)情況下,場景的前10%(近場景)將映射到0.0到0.9范圍.換句話說,90%的精度在前10%的觀察距離內(nèi)用完.如果你的算法嚴(yán)重依賴深度比較,那會很難辦.解決這個問題的方法有兩個.
1.讓深度信息線性化.![]()
2.將深度反轉(zhuǎn),后90%深度獲得前90%的精度值.
23.6 顏色緩沖區(qū)
使用GPU渲染需要涉及到許多緩沖,比如顏色緩沖,深度緩沖和模板緩沖.盡管它叫做顏色緩沖,但是它存儲的可以是任意種類的數(shù)據(jù).根據(jù)顏色的精度不同,顏色緩沖通乘澳龋可以分為幾種模式.High Color:每個像素兩個字節(jié),15或16位儲存顏色,能夠表現(xiàn)32768或65536(unsigned)顏色.True Color或RGB Color:每個像素3到4字節(jié),使用24位儲存顏色,能夠表現(xiàn)16777216種顏色.Deep Color:每個像素30,36或48個字節(jié),能夠表現(xiàn)超十億種顏色.
High Color模式的顏色,RGB每個通道至少有5位的空間,能夠有32種灰度變化.這會多出一位,多出的這一位通常會分配給綠色通道,RGB劃分為565的位存儲,因為綠色對人眼亮度影響最大,所以需要更大的表示精度.使用High Color因為每像素使用兩字節(jié)的內(nèi)存會比更高精度訪問更快.但是現(xiàn)在High Color比較少見,因為32至多64級灰度變化使相鄰顏色很容易區(qū)分,導(dǎo)致banding或者posterization的問題.這種問題的出現(xiàn)是由于人眼感知的Mach banding現(xiàn)象,會放大這些差距.通過將相鄰的顏色級別進(jìn)行混合和抖動,可以通過空間分辨率降低顏色分辨率(不懂)以減少這種影響.即使在24位顯示器上,banding還是會被注意到,向frame buffer添加噪聲可以掩蓋這個問題.
True Color使用24位的RGB顏色,每個通道1字節(jié)的空間.在PC平臺,有些情況下會存儲成BGR格式(如opencv).內(nèi)部往往會將其存儲為32位大小,因為大多數(shù)內(nèi)存系統(tǒng)對訪問4字節(jié)的元素做了優(yōu)化.有些系統(tǒng)里額外的8位用來存儲alpha通道,讓每個像素?fù)碛蠷GBA四個通道.24位的模式也被稱作壓縮像素格式(packed pixel format)相比于32位的無壓縮格式.在實時渲染中使用24位的顏色就夠了,雖然24位顏色也是會出現(xiàn)banding現(xiàn)象,但是比16位顏色更少了.
Deep Color使用30,36或48位空間的RGB顏色,也就是每個通道10,12或16位.如果加入alpha通道的話,就變成了每像素40,48,64位空間.HDMI1.3支持全部30/36/48位的模式,DP(DisplayPort)標(biāo)準(zhǔn)也支持每通道至多16位的色彩.
顏色緩沖一般會如23.5講述的被壓縮和緩存.另外,片元顏色和顏色緩沖混合的各種情況在23.10講述.光柵操作單元(raster operation unit,ROP unit)負(fù)責(zé)處理顏色混合,而且每個ROP通常連接到一個內(nèi)存分區(qū),例如使用通用的棋盤格模式(checkerboard pattern).我們接下來會介紹視頻播放控件(video display controller),它獲取一個顏色緩沖并讓其展示出來.單緩沖,雙緩沖,三緩沖也在后面介紹.
23.6.1 視頻播放控件(Video Display Controller)
在每個GPU中都存在一個視頻播放控件(VDC),也叫播放引擎(display engine)或播放接口(display interface),它負(fù)責(zé)讓顏色緩沖中的顏色播放出來.VDC是在GPU中的硬件單元,能夠支持不同接口,比如HDMI(high-definition multimedia interface),DP,DVI(digital visual interface)和VGA(video graphics array).需要播放的顏色緩沖可能位于可供CPU訪問的內(nèi)存中,或者專用的frame buffer內(nèi)存或者顯存中,前兩者都可以被CPU訪問,而顯存不能被CPU直接訪問.每個接口都使用其特定的協(xié)議來輸出顏色緩沖,時序信息甚至音頻.VDC可能也能進(jìn)行圖像縮放,降噪,多源圖像合成和其他功能.
顯示設(shè)備,如LCD,顯示刷新的速率一般在60-144Hz之間,這也叫做垂直刷新率(vertical refresh rate).大多數(shù)用戶能在72Hz以下注意到閃屏.見12.5了解更多.
顯示器技術(shù)在許多方面都有發(fā)展,如刷新率,通道位數(shù),色域和同步方面.刷新率以往是60Hz,而現(xiàn)在120Hz越來越普遍,甚至600Hz都出現(xiàn)了.高刷新率下的圖像往往會重復(fù)出現(xiàn)幾次,有時中間會插入黑幀來避免幀間移動導(dǎo)致的模糊.相對于每通道8位的表示,現(xiàn)在HDR顯示器每通道可以達(dá)到10位甚至更多.Dolby的HDR顯示技術(shù)使用較低分辨率的LED背光陣列來增強其LCD顯示器.這么做會使其能獲得相當(dāng)于普通顯示器10倍的亮度和100倍對比度.更寬色域的顯示器也會稱為趨勢.它們可以通過具有純光譜色調(diào)來顯示更廣泛的顏色,例如更生動的綠色.
為了減少撕裂效果(tearing effect),廠商也開發(fā)了自適應(yīng)同步技術(shù),如AMD的FreeSync和英偉達(dá)的G-sync.這是為了使顯示器適應(yīng)GPU的更新頻率,而不是使用固定速率.例如前一幀渲染需要10ms而后一幀需要30ms,在畫面結(jié)束渲染后會立即對顯示圖像更新.通過這種技術(shù),渲染結(jié)果的顯示會更加順滑.另外,如果圖像沒有更新,出于省電,顏色緩沖不會發(fā)送顯示.
23.6.2 單緩沖,雙緩沖,三緩沖
在2.4章我們提到雙緩沖保證了圖像在渲染完成前不會展示,在本節(jié)會介紹單緩沖,雙緩沖和三緩沖.
假設(shè)我們僅有單個緩沖.這個緩沖就是現(xiàn)在所顯示出來的內(nèi)容.隨著顯示器刷新,這一幀中的三角形一個接一個被繪制并出現(xiàn),這是個很奇怪的效果.即使幀更新率與顯示器刷新率相等時,單緩沖也是有問題的.如果我們要清除緩沖或繪制一個大三角形時,我們毫無疑問能看到VDC發(fā)送這個繪制過程.這有時被叫做撕裂(tearing),因為顯示的圖像看起來就像被撕乘兩部分一樣,這不是實時渲染所希望的特性.在一些古老的系統(tǒng)中,如Amiga中,可以通過測試電子束(beam)的位置來避免繪制這里,也就讓單緩沖能用了.現(xiàn)在單緩沖很少有人用了,虛擬現(xiàn)實系統(tǒng)可能例外,因為在虛擬現(xiàn)實中racing the beam是一種降低延遲的方法.
為了避免單緩沖的問題,如今更廣泛使用雙緩沖.渲染完成的圖像會在前緩沖(front buffer)中顯示,與此同時不可見的后緩沖(back buffer)會繪制正在渲染的圖像.然后當(dāng)整張圖像都發(fā)送到顯示器后,圖形驅(qū)動會交換前緩沖和后緩沖,這樣避免了圖像撕裂.交換操作經(jīng)常只是交換兩個顏色緩沖的指針.對于CRT顯示器,這個事件叫做垂直回溯(vertical retrace),整個過程叫做垂直同步(vertical synchronization,vsync).對于LCD顯示器,不需要物理上電子束回溯(retrace of a beam),但是我們用相同的名詞來表示顯示器的交換過程.在渲染完成后瞬時交換前后緩沖是測試一個渲染系統(tǒng)的有效指標(biāo),并且也用在其他應(yīng)用上,因為它能衡量最大幀率.不通過垂直同步刷新也會導(dǎo)致撕裂,但是因為有兩個完整的圖像,這種偽影并不會像單緩沖一樣糟糕.在交換過后,新的后緩沖負(fù)責(zé)接收圖形指令,而新的前緩沖會被呈現(xiàn)給用戶.這個過程如圖所示.
雙緩沖能夠通過增加第二個后緩沖來增強,這個緩沖稱為等待緩沖(pending buffer).這就是三緩沖.等待緩沖也像后緩沖一樣不可見,它可以在前緩沖播放出來后被修改.等待緩沖構(gòu)成了三緩沖的循環(huán)的一部分.在一幀過程中,等待緩沖會被訪問到.在下一次交換時,等待緩沖變成了后緩沖,在后緩沖處完成渲染.然后它變成前緩沖,并被用戶所見.在下次交換的過程中,前緩沖又變成了等待緩沖.這個事件過程如上圖的下部分所示.
三緩沖相比于雙緩沖有個主要的優(yōu)勢.通過使用三緩沖,系統(tǒng)能夠在等待垂直回溯的時候訪問等待緩沖.而在雙緩沖里,系統(tǒng)在等待垂直回溯時會進(jìn)行緩沖交換,所以畫面必須等待.這也就導(dǎo)致了因為前緩沖總是需要顯示,而在后緩沖完成渲染前,畫面必須保持不變(因為要等待,所以造成幀率下降).三重緩沖的缺點是延遲增加整整一幀的延遲,增加的延遲會導(dǎo)致用戶的輸入反應(yīng)延遲,如鍵鼠和手柄等.用戶可能感覺控件反映遲鈍,因為對用戶事件的反饋需要推遲到等待緩沖展示出來的時候了.
理論上來說,三個以上的緩沖也是可行的.如果計算每一幀的時間變化很大,那么更多的緩沖會平衡播放率,讓畫面更加平滑,但是代價是更高的延遲.多重緩沖可以想成一個環(huán)形結(jié)構(gòu).有一個渲染指針和展示指針,這兩個指針分別指向不同的緩沖,展示指針跟隨著渲染指針,當(dāng)當(dāng)前渲染幀已經(jīng)渲染完成后移動到下一幀.唯一規(guī)則就是展示指針不能和渲染指針指向相同.
對于PC的GPU而言,一種額外的加速方式是使用SLI模式.1998年的3dfx將SLI作為掃描線交錯的縮寫,指的是兩個圖形芯片并行運行,一個處理偶數(shù)掃描線,一個處理奇數(shù)掃描線.英偉達(dá)(收購3dfx)使用SLI的縮寫表示完全不同的一種連接兩個以上圖形卡的方式,稱為可升級鏈接界面(scalable link interface).AMD稱其為CrossFire X.這種并行形式通過將屏幕分成兩個(或兩個以上)水平部分,每個GPU渲染一部分或讓每個GPU完全呈現(xiàn)自己的幀,交替輸出來將工作進(jìn)行劃分.還有一種模式允許卡加速抗鋸齒的同一幀.最常見的用法是讓每個GPU分別渲染一個單獨的幀,稱為交替幀渲染(AFR).雖然這個方案聽起來似乎會增加延遲,但它通常很少或根本不會.假設(shè)一個單一的GPU系統(tǒng)呈現(xiàn)為10幀每秒.如果GPU是瓶頸,使用AFR的兩個GPU可以以20幀/秒的速度渲染,甚至可以以40幀/秒的速度渲染4個GPU.每個GPU渲染幀所需的時間相同,所以延遲不一定會改變.
屏幕分辨率在不斷增加,這對基于單個像素的渲染采樣來說是一個嚴(yán)峻的挑戰(zhàn).一種保持幀率的方式就是自適應(yīng)地根據(jù)屏幕和表面調(diào)整像素著色率.
23.7深度裁剪,深度測試和深度緩沖
本節(jié)將講述關(guān)于深度的內(nèi)容,包括深度分辨率,測試,裁剪,壓縮,緩存,緩沖和提前深度測試(early-z).
深度分辨率很重要因為它能幫助避免渲染的錯誤.例如,你建模了一疊紙并把它放在桌子上,距離桌子表面非常近的上方.在有精度限制的z深度下計算桌子和紙的深度,桌子可能在不同的位置與紙出現(xiàn)穿模,出現(xiàn)斑點.這個問題叫做深度沖突(z-fighting)現(xiàn)象.假設(shè)如果紙剛好放在了桌子的同樣高度,紙和桌子共面,那么需要額外的信息才能正確地描述它們的關(guān)系(深度測試無法判斷二者關(guān)系),這是由于建模錯誤導(dǎo)致的,提高z精度也無濟于事.
深度緩沖(也叫z緩沖)可以用來解決可見性問題.這種緩沖通常每像素(或每采樣點)具有24位或32位深度的浮點數(shù)或定點數(shù)表示.對于正交視角,距離量和z值成正比,所以精度分布是均勻的.而對于透視視角,精度分布是不均勻的(近處10%占用了90%的精度).在應(yīng)用透視變換后,需要做透視除法,各分量同除w分量.深度分量變成了,
是經(jīng)過mvp變換的頂點.如果z是定點數(shù)表示的,
的值還從其有效范圍被映射到了整數(shù)范圍
(b是位數(shù))并儲存在了深度緩沖中.
深度管線的硬件如圖所示.這個管線的主要目的是測試輸入的深度(該深度是光柵化面元時生成),如果該片元通過了深度測試就把輸入深度寫入到深度緩沖中.與此同時,管線需要盡可能地高效.圖片的左部分從粗糙光柵化(coarse rasterization)開始,也就是tile級別的光柵化,這時只有和面元有重疊的tile能夠進(jìn)入下一個階段,也就是深度剔除(z-culling)技術(shù)應(yīng)用的HiZ單元.
HiZ單元從叫做粗糙深度測試(coarse depth test)的塊開始,這里進(jìn)行兩個測試.一是最大深度剔除(zmax-culling),這是Greene的層級深度緩沖算法的簡化.思路是存儲tile中的深度最大值,稱作.tile的大小是根據(jù)各架構(gòu)而不同的,最廣泛的是8*8像素的.這些
值會存儲在固定的片內(nèi)存儲器(on-chip memory)或通過緩存訪問,圖中表示為HiZ cache.如果我們想測試一個三角形在該tile中是不是完全被遮擋了,我們需要計算出tile內(nèi)三角形最小的z值
,如果
,這就保證了三角形被先前tile內(nèi)渲染的幾何體遮擋了.那么在tile內(nèi)對這個三角形的處理就可以結(jié)束了,這也就節(jié)省了逐像素的深度測試.但需要注意,這并不意味著會跳過逐像素的片元著色器的執(zhí)行,因為逐像素的深度測試會結(jié)束后續(xù)管線的片元著色.在實際上,我們不會準(zhǔn)確計算
的具體值,而是會估算一個保守值.這里有兩個計算
的方法,每種都有優(yōu)缺點.
- 1.三角形三個頂點的最小z值,雖然不保證總是準(zhǔn)確,但額外計算量很小.
- 2.使用平面方程計算三角形在tile四個角的z值,并使用其中的最小值.
這兩種方法結(jié)合能實現(xiàn)最好的裁剪表現(xiàn),通過獲取兩個中的大值.
另一種粗糙深度測試的方法是最小深度剔除(zmin-culling),想法是儲存tile中的所有像素的.這個測試有兩個作用.其一,是能避免讀取深度緩沖.如果一個正在渲染的三角形相比于先前渲染的所有幾何體都絕對地靠前,那么深度測試對于它來說就是不需要的.在一些情況下,讀取深度緩沖能夠被完全避免,這能大大優(yōu)化表現(xiàn).其二,能夠用來支持不同種類的深度測試.對于zmax-culling方法,我們假設(shè)使用標(biāo)準(zhǔn)的"less than"深度測試(也就是寫入深度值更小的).然而如果裁剪過程能夠也使用其他的深度測試,并且zmin和zmax都可用的話,那么裁剪過程就能支持所有的深度測試方法(這么做確保了支持多樣的深度測試和裁剪方法).
上圖中綠色的部分用于以不同方式更新tile的和
值.如果三角形包含了整個tile,將由HiZ單元直接完成更新計算.否則,需要讀取tile內(nèi)每個采樣點的深度,并通過反饋HiZ更新(feedback HiZ update)發(fā)回HiZ單元中,這會造成一些延遲.
對于經(jīng)過粗糙深度測試的tile,會應(yīng)用邊緣函數(shù)計算像素或采樣點覆蓋,以及計算逐像素的深度(稱為深度插值,z-interpolate).這些值會發(fā)送到圖右所示的深度單元.根據(jù)API的描述,后面將跟著片元著色器.然而,在一些情況下,提前深度測試(early-z或early depth)是在片元著色器前進(jìn)行的逐像素的深度測試,被遮擋的片元會被丟棄.這個過程就避免了不必要的片元著色器執(zhí)行.提前深度測試經(jīng)常與深度剔除(z-culling)混淆,這兩個過程是分別由不同的硬件執(zhí)行的,二者的執(zhí)行是獨立的,不受對方影響.
最大深度剔除,最小深度剔除和提前深度測試是GPU在不同情況下自動執(zhí)行的.然而,比如在片元著色器寫入了自定義的深度,使用了丟棄操作或者向UAV中寫入了值,在這些情況下最大深度剔除,最小深度剔除和提前深度測試是會被關(guān)閉的.如果提前深度測試沒有使用,那么深度測試就會在片元著色器后執(zhí)行(稱作后深度測試,late depth test).
著色器資源視圖(SRV)通常以方便著色器訪問紋理的方式圍繞紋理.
無序的訪問視圖(UAV)提供類似的功能先煎,但支持以任何順序讀取和寫入到紋理(或其他資源).
環(huán)繞單個紋理可能是著色器資源視圖(SRV)最簡單的形式. 更為復(fù)雜的示例包括子資源集合(細(xì)化紋理的個別陣列、平面或顏色)巧涧、3D 紋理薯蝎、1D 紋理顏色漸變等.
無序的訪問視圖(UAV)在性能方面費用稍高,但支持同時讀/寫紋理等功能.借此,圖形管道可將已更新的紋理用于其他目的.著色器資源視圖(SRV)具有只讀用法(這是>最常見的資源用法)
在最新的硬件上,可能會支持原子的讀取-修改-寫入操作,從著色器中加載或者儲存圖像的功能.在這些情況下,你可以忽略上面的限制并顯式的啟動提前深度測試.還有個特性是,在片元著色器輸出自定義深度值是保守深度值時,也可以啟用.比如,如果程序員確保自定義深度比三角形中的深度大時,就可以開啟提前深度測試和最大深度剔除.
一般來說,從前到后的渲染有利于遮擋剔除.另一種具有類似名稱和目的的技術(shù)是z-prepass.思路是程序員首先渲染一遍場景,但僅僅寫入深度信息,關(guān)閉片元著色和顏色緩沖的寫入.當(dāng)渲染后面的pass時,只會對深度做"equal"的測試,也就是說只有最前面的面會被著色,因為深度緩沖已經(jīng)初始化完畢了.(第一遍pass只寫深度,第二遍pass做equal深度測試寫入顏色,這是軟件層面的深度測試,方便從后到前渲染時的高效渲染)
概括一下本節(jié).我們簡單介紹了深度管線的緩存和壓縮,在圖片的右下呈現(xiàn).整體的壓縮環(huán)節(jié)和23.5描述的相同.每個tile會被壓縮成一些大小,并且經(jīng)常會在壓縮失敗的時候使用非壓縮數(shù)據(jù)的回調(diào)(fallback)操作.為了在清除深度緩沖時節(jié)省帶寬占用會使用快速清除的方法.因為深度信息在屏幕空間是線性的,典型的壓縮算法要么存儲高精度的平面方程,要么使用差分技術(shù)和增量編碼,要么使用錨定方法.tile table和HiZ緩存可能會被完全儲存在on-chip內(nèi)存里,或者通過內(nèi)存層級交流,深度緩沖也是如此.on-chip的存儲開銷很大,因為需要足夠大的內(nèi)存來保證分辨率.
23.8紋理采樣
當(dāng)進(jìn)行紋理采樣操作時,會執(zhí)行獲取,過濾和解壓縮,雖然這些操作可以在GPU上運行的純軟件方式解決,但是已經(jīng)證明了使用特定功能的固件進(jìn)行紋理采樣能夠快40倍.紋理單元會對紋理格式進(jìn)行尋址,過濾,clamp和解壓操作.它和紋理緩存(texture cache)一起可以減少帶寬占用.我們首先關(guān)注過濾和它對紋理單元的影響.
為了應(yīng)用縮小過濾器,比如mipmap和各向異性過濾,需要計算紋理坐標(biāo)在屏幕空間的微分.也就是計算紋理細(xì)節(jié)LOD等級,我們需要計算
,
,
和
.它們表示,紋理的區(qū)域或功能是通過片元表現(xiàn)的.如果通過頂點著色器的紋理坐標(biāo)被用于直接從紋理中取值,然后微分會被解析地計算出來.如果紋理坐標(biāo)是通過某種函數(shù)進(jìn)行了轉(zhuǎn)換,比如
,那么解析地計算微分就會變得更加復(fù)雜,雖然也是可以使用鏈?zhǔn)椒▌t和符號微分來計算的.盡管如此,GPU并不專門提供圖形硬件層面的支持,因為計算可能非常復(fù)雜.想象用環(huán)境光貼圖為帶有凹凸貼圖的表面計算反射,這時候要得到反射向量的微分,是很難解析地計算出來的.所以,微分總是在一個quad(也就是2*2的像素)中,數(shù)值地計算x與y的差分.這也是GPU將quad作為調(diào)度單位的原因.
一般來說,微分計算總是在后臺的,也就是用戶不可見的.實際的實現(xiàn)方式通常是在一個quad上應(yīng)用cross-lane指令(shuffle/swizzle),編譯器會自動插入這些指令.一些GPU會使用混合函數(shù)(mixed-function)硬件來計算這些微分.沒有固定計算微分的方式.一些廣泛用的方法在圖里標(biāo)明了.OpenGL4.5和DirectX 11都支持了計算粗細(xì)導(dǎo)數(shù)的函數(shù).
紋理坐標(biāo)的計算方式.一種是計算quad四點處
所有的GPU都會進(jìn)行紋理緩存,目的是減少紋理對于帶寬的占用.一些架構(gòu)使用專用的紋理緩存,或者甚至兩個專用的紋理緩存級別,而一些架構(gòu)對所有緩存的訪問都使用共享的緩存.通常使用小型的on-chip內(nèi)存(通常為SRAM)來實現(xiàn)紋理緩存.這個緩存儲存了最近的紋理讀取結(jié)果,擁有很快的訪問速度.緩存置換方法和大小是取決于架構(gòu)的.如果相鄰像素需要訪問相同或附近的紋素塊,通常在紋理緩存里會訪問.正如23.4提到的,紋理在GPU中通常是喲你tiled的順序存儲,如4*\4紋素,而非采用掃描線順序存儲,由于一個tile的紋素都是一起獲取的,所以這能提高訪問效率.tile的內(nèi)存大小一般是和緩存中線大小相同,比如64字節(jié).另一種存儲紋理的方式是使用swizzled模式.假設(shè)紋理坐標(biāo)已經(jīng)轉(zhuǎn)換成了定點數(shù),每個
占用
位.
的第
位表示為
.然后重映射
到swizzled紋理坐標(biāo)
是紋理的初始地址,
是一個紋素占用的內(nèi)存大小.重新映射的方法的優(yōu)點是能夠讓紋素保持如圖所示的連續(xù)增加的內(nèi)存分布.這是一種叫Morton sequence的空間填充曲線(space-filling curve),它經(jīng)常用來改進(jìn)一致性.在紋理坐標(biāo)方面,Morton sequence是二維的,紋理剛好也是二維的.
紋理單元中會包含不同的解壓紋理格式的結(jié)構(gòu).使用硬件級的支持要比軟件級的支持效率提高數(shù)倍.注意到當(dāng)使用紋理圖當(dāng)作渲染對象和紋理貼圖時會出現(xiàn)其他的壓縮機會.如果啟動了顏色緩沖的壓縮,那么當(dāng)以紋理的形式訪問這個渲染對象時有兩個設(shè)計選項.當(dāng)渲染對象結(jié)束了它的渲染過程,一個選項是從顏色緩沖的壓縮格式中解壓縮出整個渲染對象,然后將其以菲亞所的方式存儲方便后續(xù)訪問.第二個選項是,在紋理單元中增加對顏色緩沖壓縮格式解壓的硬件支持.后者是更加高效的選擇,因為渲染對象會在訪問過程中保持壓縮狀態(tài).了解更多壓縮和緩沖請看23.4
Mipmap對于提高紋理采樣緩存局部性很重要,因為它可以最大化紋素-像素比例.當(dāng)遍歷三角形時,每個新像素盡可能對應(yīng)紋理空間的一個紋素.Mipmap是提升視覺和性能的幾種渲染技術(shù)之一.
23.9 架構(gòu)
實現(xiàn)快速的圖形處理的最好方式就是應(yīng)用并行性,GPU能夠在幾乎所有階段實現(xiàn)并行.思路是同時計算多個結(jié)果并將這些結(jié)果在后續(xù)階段融合操作.總體上,一個并行的圖形架構(gòu)會是如圖所示的樣子.分為四個階段.應(yīng)用階段為GPU發(fā)送任務(wù),經(jīng)過調(diào)度,進(jìn)入幾何處理階段.幾何階段由諸多幾何單元(geometry unit)并行處理.幾何階段后是光柵化階段,幾何單元的處理結(jié)果會進(jìn)入一組光柵化單元(rasterizer unit)中,在光柵化單元進(jìn)行光柵化.下一階段是片元著色和融合階段,也是通過像素處理單元(pixel processing unit)并行執(zhí)行的.最終結(jié)果圖像會發(fā)送到顯示器.
對于硬件和軟件來說,弄清楚你的硬件或代碼中是否有串行的部分是很關(guān)鍵的,它會限制你可能的性能改進(jìn)總量.Amdahl法則(Amdahl's law)有以下表述:
是程序或硬件串行的比例,
是適合并行的比例,
是通過將程序或硬件并行化能夠獲得最大性能提升的倍數(shù).例如,如果我們本來有一個多處理器,額外增加了三個,那么
.這里
是能從改進(jìn)中獲得的加速倍數(shù).如果我們有一個架構(gòu),實現(xiàn)了10%串行,也就是
,我們改進(jìn)了架構(gòu),使剩余的(非串行)部分能改進(jìn)20倍,也就是
,于是我們有
.我們能看到,并非提速了20倍,因為程序或硬件中串行的部分嚴(yán)重地限制了性能.事實上,當(dāng)
時,
.應(yīng)該花費精力在改進(jìn)并行部分還是串行部分并不總是清晰的,但是當(dāng)并行部分得到大幅改進(jìn)后,串行的部分會更加限制性能.
對于圖形架構(gòu)而言,許多結(jié)果是并行計算出來的,但是draw call中的面元是按它們被CPU提交的順序處理的.所以,需要進(jìn)行排序以保證并行的單元能一同渲染出用戶需要的圖像.具體地講,需要從模型空間到屏幕空間進(jìn)行排序.需要注意的是,幾何單元和像素處理單元可能被映射到相同的單位,即統(tǒng)一的ALU.我們23.10講的所有的架構(gòu)使用統(tǒng)一的著色器架構(gòu)(unified shader architectures).即使這樣,了解排序發(fā)生的位置也很重要.我們對并行架構(gòu)進(jìn)行分類.排序可能會發(fā)生在管線的任何位置,這會導(dǎo)致并行架構(gòu)中的四個不同種類的工作分布,如圖23.17所示.被稱為sort-first, sort-middle, sort-last fragment,和sort-last image.注意這些架構(gòu)導(dǎo)致了GPU在并行單元中分配工作的不同方式.
sort-first-based架構(gòu)在幾何階段前排序面元.策略是將屏幕劃分為一系列區(qū)域,區(qū)域中的面元被送入負(fù)責(zé)這個區(qū)域的一條完整的管線中.如圖所示.在排序的步驟中,對面元的初始處理就足以讓它知道該被送入哪個區(qū)域.對于機器而言,sort-first模式是最后一種被使用的架構(gòu).當(dāng)驅(qū)動一個包含多個屏幕或形成一個大屏幕的投影儀的系統(tǒng)時,它確實是一種有用的方案,因為單個計算機專用于每個屏幕.有一種名為Chromium的系統(tǒng),它可以使用一組工作站實現(xiàn)任何類型的并行渲染算法.例如,sort-first和sort-last能夠高性能地渲染.
Mali架構(gòu)是一種sort-middle的架構(gòu).每個幾何處理單元處理的幾何體數(shù)量大致相同.然后經(jīng)過變換的幾何體會被排序到不重合的矩形中,稱為tiles,所有的tiles覆蓋了整個屏幕.注意一個經(jīng)過變換的三角形可能會與幾個tile重合,也就是會被不同的光柵化單元和像素單元處理.高效處理的關(guān)鍵是每個光柵化單元和像素處理單元的對,擁有一個與tile相同大小的(tile-sized)on-chip幀緩沖,這意味著所有幀緩沖的訪問速度都很快.當(dāng)所有的幾何體都被排序為tiles,對每個tile的光柵化和像素處理就會獨立地進(jìn)行.一些sort-middle架構(gòu),在對tile處理時,針對不透明的幾何體應(yīng)用提前深度測試,這也就意味著每個像素只會被著色一次.然而,不是所有的sort-middle架構(gòu)都這樣做.
sort-last fragment架構(gòu)在光柵化(有時叫做片元生成)后,在像素處理前對片元進(jìn)行排序.例如23.10.3介紹的GCN架構(gòu).正如sort-middle架構(gòu),面元被盡可能均勻地分發(fā)給了幾何單元.一個sort-last fragment架構(gòu)的優(yōu)點是不會有任何的遮擋,也就是說一個生成的片元會被發(fā)送到一個像素處理單元中,這正是最優(yōu)情況.如果一個光柵化單元處理巨大的三角形而另一個處理小三角形時,便會變得不平衡.
sort-last image架構(gòu)在像素處理后進(jìn)行排序.如圖所示.整個架構(gòu)能被看作是獨立的管線的集合.面元被分配給管線,每個管線渲染一個帶有深度信息的圖像.在最后的組合階段,所有的圖像會被根據(jù)其各自深度緩沖混合.需要注意的是sort-last image系統(tǒng)不能完全被OpenGL和DirectX執(zhí)行,因為它們需要面元以發(fā)送的順序渲染.PixelFlow是sort-last image架構(gòu)的例子.PixelFlow架構(gòu)需要注意它使用延遲著色,也就是說它只會為看得見的片元著色.要注意因為管線尾端的大量帶寬占用問題,并沒有現(xiàn)有的架構(gòu)使用sort-last image架構(gòu).
純粹的sort-last image主題在large tiled display系統(tǒng)上的一個問題是,需要在渲染節(jié)點之間傳輸?shù)拇罅繄D像和深度數(shù)據(jù),Roth 和 reiner的方法通過使用每個處理器結(jié)果的屏幕和深度邊界來優(yōu)化數(shù)據(jù)傳輸和組合成本.
Eldridge等人提出了Pomegranate架構(gòu),是一種任意階段排序的架構(gòu).簡單來說,它在幾何階段和光柵化單元之間,在光柵化單元和像素處理單元之間,像素處理單元和展示之間,都插入了排序階段.因此隨著系統(tǒng)規(guī)模的擴大,工作會更加保持平衡(因為增加了更多的管線).排序階段通過帶有點對點連接的高速網(wǎng)絡(luò)實現(xiàn).模擬結(jié)果顯示,它能夠隨更多的管線加入,達(dá)到近乎線性的優(yōu)化表現(xiàn).
圖形系統(tǒng)的所有組成部分(主機,幾何處理,光柵化和像素處理)相互連接并構(gòu)成了一個多處理系統(tǒng).在這種系統(tǒng)中,有兩個與多處理相關(guān)的問題:負(fù)載均衡(load balancing)和通信(communication).FIFO(first-in first-out)隊列隊列通常插入到管線中的許多不同位置,因此可以排隊執(zhí)行任務(wù),以避免管線的部分停止.例如,可以在幾何單元和光柵化單元之間放置FIFO,可以將經(jīng)過幾何處理的三角形放入緩沖,以免由于三角形過大(等原因)導(dǎo)致光柵化單元跟不上幾何單元的處理節(jié)奏.
不同的排序架構(gòu)描述有各自不同的負(fù)載均衡優(yōu)缺點.參考Eldridge’s PhD理論或Molnar et al的論文了解更多.編程者也可以影響負(fù)載均衡,相關(guān)技術(shù)在18章介紹.如果總線帶寬過低或低效利用的話,通信也會變成問題.有必要設(shè)計一套應(yīng)用上的渲染系統(tǒng),使性能瓶頸避開總線,也就是從主機到圖形硬件的總線.18.2章介紹了檢測瓶頸的不同方法.
23.10 GPU架構(gòu)案例
在這節(jié),我們將介紹三個不同的圖形硬件架構(gòu).首先介紹ARM Mali G71 Bifrost架構(gòu),主要應(yīng)用于移動設(shè)備和電視.其次是NVIDIA的Pascal架構(gòu).最后介紹AMD GCN架構(gòu)Vega.
注意圖形硬件廠商的設(shè)計決策通常是建立在對還沒有實現(xiàn)的GPU進(jìn)行大量軟件模擬的基礎(chǔ)上的.也就是說,建立一個參數(shù)化的軟件模擬體系,一些應(yīng)用如游戲,配置不同的參數(shù)運行在這些參數(shù)化軟件模擬系統(tǒng)上.比如說,可能的參數(shù)有MP的個數(shù),時鐘頻率,緩存的數(shù)量,光柵化引擎/細(xì)分曲面引擎的數(shù)量,光柵化處理器(ROP)的數(shù)量等.此模擬器是用于收集這些參數(shù)對于性能,耗電量,內(nèi)存帶寬占用等的信息.在最后,能在大多數(shù)情況下運行得最優(yōu)的參數(shù)配置會被選中,并依照此參數(shù)配置生產(chǎn)出芯片.另外,模擬器也能找出架構(gòu)中的性能瓶頸,以便針對性地解決,比如增加緩存的大小.對于某個特定的GPU,使用不同速度和數(shù)量的單元的原因很簡單,"it works best this way".(別問,問就是it works)
23.10.1 案例學(xué)習(xí)ARM Mali G71 Bifrost
Mali產(chǎn)品線包含了ARM的所有GPU架構(gòu),Bifrost是其2016年以來的架構(gòu).這個架構(gòu)的目的是移動端和嵌入式系統(tǒng),比如手機,平板和電視.2015年,基于Mali的GPU出貨了7.5億片.因為許多芯片是用電池供電的,Mali產(chǎn)品線GPU的架構(gòu)設(shè)計會關(guān)注節(jié)能而不是性能表現(xiàn).于是,這使得sort-middle架構(gòu)成為可能,因為sort-middle架構(gòu)所有幀緩沖訪問在芯片中,這種設(shè)計降低了能源消耗.所有Mali架構(gòu)都是sort-middle類型的,有時也稱為tiling架構(gòu).這種GPU的總覽如圖所示.G71能支持至多32個統(tǒng)一的著色器引擎(shader engine).ARM使用著色器核心(shader core)指代著色器引擎,但是我們繼續(xù)使用著色器引擎以避免用詞沖突.一個著色器核心一次性能夠執(zhí)行12個線程,也就是說它擁有12個ALU.32個著色器核心是專為G71設(shè)計的,但是它可以擴展到32個以上的數(shù)量.
驅(qū)動軟件為GPU分配工作.作業(yè)管理器(job manager)也就是調(diào)度器(scheduler)將工作分發(fā)到著色器引擎上.所有的引擎通過GPU fabric連接在一起,GPU fabric是一個著色器引擎能和其他引擎通信的總線.所有的內(nèi)存訪問是通過內(nèi)存管理單元(memory management unit,MMU)發(fā)送,它能將虛擬內(nèi)存地址轉(zhuǎn)換為物理內(nèi)存地址.
一個著色器引擎的總覽如下圖所示.能夠看到,它包含三個執(zhí)行引擎(execution engine),以對quad的著色為核心.而且,這些執(zhí)行引擎被設(shè)計為SIMD寬度為4的小型通用處理器.每個執(zhí)行引擎包含4個用于32位浮點數(shù)的混合乘加單元(fused-multiply-and-add,FMA unit)和四個32位加法器.也就是說每個著色器引擎擁有3*4個ALU(執(zhí)行引擎4個ALU),也就是12個SIMD通道.一個quad也就相當(dāng)于一個warp.為了隱藏訪問紋理的延遲,每個著色器引擎能同時保持256個線程.
需要注意著色器引擎是統(tǒng)一的,能夠執(zhí)行計算著色,頂點著色和片元著色等.執(zhí)行引擎也支持許多超越函數(shù)計算比如和
.另外,當(dāng)使用16為浮點數(shù)精度時,性能會提升兩倍.這些單元還支持在寄存器結(jié)果只用作后續(xù)指令的輸入時,繞過寄存器的內(nèi)容,因為寄存器文件不需要被訪問,所以會省電.另外,比如當(dāng)訪問紋理或其他內(nèi)存時,quad管理器會將一個quad切換進(jìn)來(訪問紋理很耗時),就像其他的架構(gòu)在遇到訪問紋理等操作時需要隱藏延遲一樣.注意這發(fā)生在小粒度層面,交換4個線程而不是全部12線程.讀取/儲存單元(load/store unit)負(fù)責(zé)處理一般的內(nèi)存訪問,內(nèi)存尋址轉(zhuǎn)換和一致性緩存.屬性單元(attribute unit)處理屬性索引和尋址,它將訪問信息輸送給讀取/存儲單元.變化單元(varying unit)執(zhí)行變化屬性(varying attribute)的插值.
tiling架構(gòu)(sort-middle架構(gòu))的核心思想是首先執(zhí)行幾何處理,以便找到每個要渲染的圖元的屏幕空間位置.同時為幀緩沖(framebuffer)中的每個tile建立一個包含著各個圖元重疊哪個tile的指針的多邊形列表(polygon list).這步以后,與tile重疊的圖元的集合就已知了.于是,tile中的圖元就能被光柵化和著色,結(jié)果儲存在on-chip tile內(nèi)存中.當(dāng)tile渲染完畢它中的所有面元,tile內(nèi)存的數(shù)據(jù)會通過L2緩存寫回到外部內(nèi)存中,這樣減少了內(nèi)存帶寬占用.接著下一個tile被光柵化,然后接著,直到整個幀都渲染完成.第一個tiling架構(gòu)是Pixel-Planes 5,這個架構(gòu)在高層上和Mali架構(gòu)很相似.
幾何處理和像素處理的過層如圖所示.如上圖所示,頂點著色器被分成了兩份,一個只進(jìn)行位置著色,另一個被稱為變化著色在tiling環(huán)節(jié)之后完成.這種結(jié)構(gòu)相比于ARM以前的架構(gòu)來說更加節(jié)省內(nèi)存帶寬.分揀操作(binning)確定哪些tile與圖元重疊,其需要的唯一信息是頂點位置.分片器單元(tiler unit)如下圖所示,按層級的方式執(zhí)行分揀(binning)操作.這有助于使分揀操作內(nèi)存占用更小,更可預(yù)測,因為它不與圖元大小成正比(也就是說層級大小固定).
當(dāng)分片器結(jié)束為所有場景中的圖元分揀后,它已經(jīng)完全知道哪個圖元和某個tile重疊的信息.于是,剩下的光柵化,像素處理,混合等流程對于任何數(shù)量的tile都可以進(jìn)行并行處理了,當(dāng)然要在著色器引擎能并行處理的個數(shù)范圍內(nèi).一般來說,一個tile要被提交到著色器引擎,由該引擎處理所有在此tile中的圖元.當(dāng)每個tile的工作都完成后,就可以開始為下一幀的渲染進(jìn)行幾何處理和分片了.這個處理模型意味著在tiling架構(gòu)中會出現(xiàn)更多的延遲.(不懂)
此時,接下來是光柵化,片元著色器處理,混合和其他逐像素的操作.tiling架構(gòu)最簡單重要的特性是為每一個tile的幀緩沖(包括顏色,深度,模板等),能夠存儲于on-chip內(nèi)存中,稱之為tile內(nèi)存.這個開銷很小,因為tile只有16*16的大小,是很小的.當(dāng)tile內(nèi)的全部渲染完成后,tile所需的輸出(通常是顏色,有時是深度)會拷貝到一個與屏幕大小相同的off-chip緩沖內(nèi)(位于外部存儲中).這意味著在像素處理過程中所有對于幀緩沖的訪問會高效到近于零開銷.因為使用總線的能量消費非常高,所以非常需要避免使用外部總線.當(dāng)從on-chip tile內(nèi)存向off-chip幀緩沖交換數(shù)據(jù)時,幀緩沖也可以用壓縮的形式.
Bifrost支持像素本地儲存(pixel local storage,PLS),一種通常被sort-middle架構(gòu)支持的拓展集.通過PLS,可以讓片元著色器訪問幀緩沖中的顏色并從而使用自定義混合技術(shù)(custom blending techniques).相對地,混合一般通過API配置并且是不允許通過片元著色器編程的.我們也可以使用tile內(nèi)存存儲任意固定大小的數(shù)據(jù)結(jié)構(gòu).這就允許了程序員高效地實現(xiàn)例如延遲著色技術(shù).G-buffer(如法線,位置和漫反射紋理)在第一個pass中被存入PLS.在第二個pass執(zhí)行光照計算,并積累結(jié)果存入PLS.在第三個pass應(yīng)用PLS中的信息計算最終的像素顏色.對于單個的tile,所有計算都發(fā)生在整個tile內(nèi)存還on-chip的情況下進(jìn)行的,因為這能加快速度.
所有Mali架構(gòu)在設(shè)計時都考慮到了MSAA,它們實現(xiàn)了第143頁所述的旋轉(zhuǎn)網(wǎng)格超采樣(RGSS)方案,每個像素4個采樣點.sort-middle架構(gòu)非常適合抗鋸齒設(shè)計.這是因為在tile離開GPU被送往外部內(nèi)存的前一步實現(xiàn)了過濾.因此外部內(nèi)存的中的幀緩沖只需要存儲每個像素一個顏色.標(biāo)準(zhǔn)的架構(gòu)需要四倍大的幀緩沖.對于tiling架構(gòu),只需要增加四倍的on-chip的tile緩沖,或者高效地使用更小的tile(寬度和高度的一半).
Mali Bifrost架構(gòu)能選擇性地在一組渲染圖元中選擇使用多采樣(multisampling)或超采樣(supersampling).這意味著在一個像素內(nèi)多個采樣點都分別執(zhí)行一次片元著色器的昂貴的超采樣方法,也能隨需求使用.舉例來說是使用alpha映射渲染紋理樹,在這里需要高質(zhì)量地采樣來避免視覺偽影,對于這里的圖元而言,需要開啟超采樣.當(dāng)復(fù)雜的情況結(jié)束,需要渲染的只是簡單的物體,我們可以切換回使用更小開支的多采樣方法.此架構(gòu)也支持8倍和16倍MSAA.
Bifrost(和其前身架構(gòu)Midgard)也支持一種叫做事物消除(transaction elimination)的技術(shù).它的思路是避免不是本場景完整的一幀的幀緩沖從on-chip到off-chip的內(nèi)存轉(zhuǎn)換(避免部分tile的幀緩沖內(nèi)存轉(zhuǎn)換).對于當(dāng)前幀,每當(dāng)tile內(nèi)存被轉(zhuǎn)換,會為該tile計算一個唯一的標(biāo)識.這個標(biāo)識是一種校驗和.對于下一幀會在當(dāng)tile的內(nèi)存即將要轉(zhuǎn)換時計算校驗和.如果某一tile前一幀的標(biāo)識和當(dāng)前幀的標(biāo)識是相同的,那么架構(gòu)會避免將on-chip內(nèi)存寫出到off-chip內(nèi)存中,因為這個tile兩幀是一樣的,而上一幀的內(nèi)存已經(jīng)寫好了.事實上,這在許多移動游戲中很有用,比如憤怒的小鳥,因為一幀中只有很少部分需要更新.注意到這種技術(shù)在sort-last架構(gòu)中的應(yīng)用是不同的,因為sort-last架構(gòu)不是基于tile的處理.G71也支持智能組合(smart composition),它能夠應(yīng)用在用戶接口組合時實現(xiàn)事務(wù)消除.如果一塊像素中所有源都和前一幀相同并且操作也都相同,那么可以避免讀取,組合,寫入這塊像素.
低等級的省電技術(shù)也在這架構(gòu)中頻繁使用,例如時鐘門控(clock gating)和電源門控(power gating).這意味著管線中未使用的或不積極的部分會關(guān)閉或者保持低能耗待機來降低電能使用.為了減少紋理帶寬,該架構(gòu)還準(zhǔn)備了獨立的解壓縮單元用于ASTC和ETC.另外,壓縮的紋理以壓縮形式儲存在緩存中,而不是解壓以后將紋素放入緩存中.這意味著每當(dāng)需要訪問紋素,硬件會在緩存中讀取塊然后動態(tài)解壓縮塊中的紋素.這種設(shè)置可以增加緩存中的可用區(qū)域大小,并提高效率.
總體來說,tiling架構(gòu)的一個優(yōu)勢是它天生地設(shè)計了tile的并行處理結(jié)構(gòu).比如說,所有著色器引擎可以同一時間獨立地渲染各自的tile,更多的著色器引擎也可以添加進(jìn)來.tiling架構(gòu)的缺點是整個場景的數(shù)據(jù)需要發(fā)送到GPU中分片,并將處理后的幾何體流傳送到內(nèi)存中去.總的來說,sort-middle架構(gòu)并不是處理幾何體放大的理想選擇,比如應(yīng)用幾何著色器和細(xì)分曲面,因為更多幾何體會增加用于前后shuffling幾何體的內(nèi)存?zhèn)鬏斄?對于Mali架構(gòu),幾何著色和細(xì)分曲面都是GPU上用軟件實現(xiàn)的,而且'Mali best practices guide'建議永遠(yuǎn)不要用幾何著色器.對于大多數(shù)內(nèi)容,sort-middle架構(gòu)能夠在移動設(shè)備和嵌入式系統(tǒng)中表現(xiàn)很好.
23.10.2 案例學(xué)習(xí):英偉達(dá)Pascal
Pascal是英偉達(dá)的GPU架構(gòu),它包含了圖形部分和計算部分,計算部分針對的是高性能計算和深度學(xué)習(xí)應(yīng)用.在這節(jié)我們主要關(guān)注圖形部分,具體地尤其是在GTX1080.我們會自下而上地介紹,從最小的同一的ALU開始,然后構(gòu)建起整個GPU.在這一節(jié)的結(jié)尾,我們會簡要提到其他的芯片.
英偉達(dá)把Pascal圖形架構(gòu)中使用的統(tǒng)一的ALU稱為CUDA核心(CUDA core),其高層圖如上圖左側(cè)所示.ALU的中點是浮點數(shù)和整數(shù)運算,但是它們都支持其他操作.為了增加計算性能,幾個這樣的ALU被組合成了流處理器(streaming multiprocessor,SM).在Pascal的圖形部分,SM包括四個處理塊(processing block),每個處理塊擁有32個ALU.這意味著SM能同時處理4個warps每個擁有32線程.如下圖所示.
GTX1080共有2560個CUDA核心,也就是說總共80個處理塊,20個SM
處理塊也可以叫做寬度為32的SIMT引擎,每個處理塊擁有8個讀取/儲存單元(load/store unit,LD/ST unit)和8個特別功能單元(special function unit,SFU).讀取/存儲單元負(fù)責(zé)向寄存器文件內(nèi)的寄存器中讀取和寫入數(shù)值,寄存器文件大小為16k*4B,也就是每個處理塊中的寄存器文件有64kB,加起來每個SM有64kB*4的寄存器文件大小.SFU處理超越函數(shù)指令,如sin,cos,exp2,log2,倒數(shù)和倒數(shù)平方根.還支持屬性插值.
SM中的所有ALU共享一個指令緩存,而每個SIMT引擎(處理塊)擁有獨占的指令緩沖,緩沖區(qū)里包含最近讀取的指令集合以提高指令緩存命中率.warp調(diào)度器每個時鐘循環(huán)負(fù)責(zé)分發(fā)兩個warp指令,例如,在同一時鐘循環(huán)中工作能夠同時調(diào)度給ALU和LD/ST單元.注意每個SM中有兩個L1緩存,每個緩存24kB,也就是每個SM內(nèi)48kB的L1緩存.使用兩個L1緩存是因為如果使用更大的L1緩存會需要更多的讀與寫端口,這會增加緩存的復(fù)雜性并導(dǎo)致芯片上的緩存面積更大.另外,每個SM有8個紋理單元.
由于渲染需要在2*2像素的quad中完成,warp調(diào)度器找到8個不同像素的quad并且將他們組合在32個SIMT通道中執(zhí)行.由于統(tǒng)一的ALU設(shè)計,wrap調(diào)度器能組合頂點著色器,片元著色器,圖元或計算著色器,進(jìn)入warp中工作.注意SM能同時處理不同種類的warps(如頂點,片元和圖元).這架構(gòu)也能零重疊地來切出當(dāng)前執(zhí)行的warp到準(zhǔn)備執(zhí)行的warp.Pascal會挑選什么樣的warp來執(zhí)行的細(xì)節(jié)我們不得而知,但是從英偉達(dá)以前的架構(gòu)或許能找到暗示.在英偉達(dá)2008年的架構(gòu)Tesla中,一個記分版(scoreboard)被用來衡量每個時鐘循環(huán)中每個warp.記分板是一種通用的機制,允許無沖突地?zé)o序執(zhí)行.warp調(diào)度器在warps中選擇準(zhǔn)備好執(zhí)行的warp,比如不在等待紋理讀取返回的warp,然后選擇一個給予最高優(yōu)先級.warp類型,指令類型,和公平性是選擇最高優(yōu)先級warp的依據(jù).
SM是和polymorph引擎(PM)組合工作的.這個單元是在Fermi芯片的第一個實現(xiàn)中出現(xiàn)的.PM執(zhí)行數(shù)個幾何相關(guān)任務(wù)(geometry-related tasks)包括頂點獲取,細(xì)分曲面,同時多投影(simultaneous multi-projection),屬性裝配和流輸出.第一個階段從全局頂點緩沖獲取頂點并分發(fā)warps給SM用于頂點和hull著色.然后接著是可選的細(xì)分曲面階段,這個階段新生成的patch坐標(biāo)被分配給SM進(jìn)行域著色(domain shading)和可選的幾何著色.第三階段處理視口變換和透視校正.另外,可選的同時多投影步驟在此執(zhí)行,比如它能讓VR渲染更高效.接下來是可選的第四階段,這里頂點以流的方式輸出到內(nèi)存.最終,結(jié)果被提交到相關(guān)的光柵引擎(raster engine)中.
光柵引擎有三個任務(wù),三角形裝配,三角形遍歷和深度剔除(z-culling).三角形裝配獲取頂點,計算邊緣函數(shù),然后執(zhí)行背面剔除(backface culling).三角形遍歷使用層級tile遍歷技術(shù)(hierarchical tiled traversal technique)來訪問與三角形重疊的tile.它使用邊緣函數(shù)執(zhí)行tile測試以及執(zhí)行內(nèi)部測試.在Fermi架構(gòu)里,每個光柵化器每個時鐘循環(huán)內(nèi)能處理至多8個像素.對此Pascal并沒有公開的數(shù)據(jù).深度剔除單元處理基于逐個tile的剔除,使用23.7提到的技術(shù).如果一個tile被剔除完畢,那么這個tile的進(jìn)行會被立刻終止.對于留下來的三角形,逐頂點的屬性會被轉(zhuǎn)換進(jìn)平面方程,為了在片元著色器中的表現(xiàn)更加高效.
流處理器(streaming processor)與polymorph引擎的組合叫做紋理處理簇(texture processing cluster,TPC).在更高一層,5個TPC一組組成圖形處理簇(graphics processing cluster,GPC),由一個光柵引擎伺服5個TPC.一個GPC可以看作一個小的GPU,它的目的是組成均衡的硬件單元集,提供圖形處理的功能,如頂點,幾何,光柵,紋理,像素和ROP單元.我們會在本節(jié)最后看到,創(chuàng)建獨立的功能單元可以讓設(shè)計人員更容易地創(chuàng)建一個具有一系列功能的GPU芯片家族.
到此我們有了構(gòu)成GTX1080的大多數(shù)塊.它包括四個GPC,總體如圖所示.注意到圖中有另一級別的調(diào)度器,有GigaThread engine驅(qū)動,在PCIev3的接口旁邊.GigaThread engine是一個全局工作分配引擎,為所有GPC調(diào)配線程.
光柵操作單元(raster operation unit,ROP unit)也在圖中有顯示,盡管有隱藏.他們位于中間的L2緩存的正上方和正下方.每個塊是一個ROP單元,被分成了8組,每個組有8個ROP,共有64個ROP.ROP單元的主要任務(wù)是寫入輸出到像素和其他緩沖,以及進(jìn)行多種操作,例如混合.如圖左側(cè)和右側(cè)所示,一共有8個32位內(nèi)存控制器,一共是256位.8個ROP單元與一個內(nèi)存控制器和256kB的L2緩存綁定(每組一個控制器和256kB緩存).每個芯片提供了總共2MB的L2緩存.每個ROP綁定到了一個特定的內(nèi)存分區(qū),這意味著一個ROP處理緩沖中特定子集的一些像素.ROP單元也處理無損的壓縮.共支持三種壓縮格式,另外還支持解壓和快速清除(fast clear).對于2:1壓縮(也就是256B壓縮到128B),每個tile會存入一個參考顏色值,各像素與參考顏色的插值會被編碼,插值編碼會比原本顏色編碼更省空間.4:1的壓縮是2:1壓縮的拓展,這個模式只會在插值能被使用更少空間編碼的情況下才會采用(能壓才壓,不強求),而且它只能在tile內(nèi)容平滑變化的情況下.也有8:1壓縮的模式,8:1壓縮是把2*2像素塊的4:1恒定顏色壓縮,應(yīng)用了2:1壓縮.GPU總會使用最高壓縮率的模式,8:1優(yōu)先級高于4:1高于2:1,當(dāng)所有的壓縮嘗試都失敗后,tile會被轉(zhuǎn)換并以非壓縮的方式存儲在內(nèi)存中.Pascal壓縮系統(tǒng)的效率如圖所示.
Pascal架構(gòu)使用的顯存是GDDRX5,時鐘頻率是10GHz.上面我們看到8個內(nèi)存控制器提供了總共256位,也就是32B.這提供了總共320GB/s的最高內(nèi)存帶寬,但是帶有壓縮技術(shù)的多級緩存能提供更高效的頻率.
芯片的基礎(chǔ)時鐘頻率是1607MHz,當(dāng)電力充足時它能經(jīng)常以1733MHz的增壓模式(boost mode)運行.峰值計算能力是(浮點數(shù)運算個數(shù)):
其中,2是融合乘加經(jīng)常被當(dāng)作兩個浮點數(shù)運算,然后我們除了來將MFLOPS轉(zhuǎn)換成TFLOPS.
英偉達(dá)開發(fā)了很長時間的sort-last fragment架構(gòu).然而從Maxwell開始,它們支持了一種新的渲染類型叫tiled caching,這是介于sort-middle和sort-last fragment的某種方式.這個架構(gòu)如圖所示.思路是應(yīng)用局部性和L2緩存.幾何體在足夠小的chunk中,所以能夠輸出并留在緩存中.另外,只要與tile重疊的幾何體沒完成像素著色,幀緩沖也會一直留在L2中.
在GTX1080的圖中,有四個光柵引擎,但是我們知道圖形API(大多數(shù)情況下)必須遵守圖元提交順序.幀緩沖也經(jīng)常通過生成的記錄板模式分割成tiles,然后每個光柵引擎各自擁有一組tiles.當(dāng)前的三角形被送到至少有一個tile與三角形重疊的光柵引擎中,每個光柵引擎獨立解決tile的排序問題.這樣能更好地負(fù)載均衡.GPU架構(gòu)中也有許多FIFO隊列,用于減少硬件單元的饑餓感(不理解).隊列沒在圖中畫出來.
播放控件擁有每個顏色分量12位大小,能提供BT.2020寬的色域支持.它也支持HDMI2.0b和HDCP2.2.對于視頻處理,它支持SMPTE 2084,一個針對高動態(tài)范圍視頻的轉(zhuǎn)換方法.Venkataraman描述了英偉達(dá)架構(gòu)從Fermi及之后的架構(gòu)如何擁有一個或多個拷貝引擎(copy engine).這些都是可以執(zhí)行直接內(nèi)存訪問(direct memory access,DMA)變換的內(nèi)存控件.DMA變換出現(xiàn)在CPU和GPU之間,這種變換會出現(xiàn)在它們中的任何一個上.開始處理單元(starting processing unit)能在轉(zhuǎn)換過程中繼續(xù)進(jìn)行其他的計算.拷貝引擎能初始化CPU和GPU內(nèi)存間的DMA數(shù)據(jù)轉(zhuǎn)換,拷貝引擎能獨立于GPU的其他部分執(zhí)行.于是,GPU能在信息從CPU到GPU傳送的過程中(反之亦然),渲染三角形和進(jìn)行其他操作.
Pascal架構(gòu)也能配置用于非圖形的應(yīng)用,例如訓(xùn)練神經(jīng)網(wǎng)絡(luò)或大規(guī)模數(shù)據(jù)分析,Tesla P100就是其中一種配置,與GTX1080的區(qū)別包括它使用高帶寬內(nèi)存2(high-bandwidth memory 2,HBM2)擁有4096位用于內(nèi)存總線,提供總內(nèi)存帶寬720GB/s.另外,提供原生的16位浮點數(shù)支持,能夠比32位浮點數(shù)提高兩倍的性能和更快速的雙精度處理.SM的配置也不同,寄存器文件設(shè)置(register file setup)也不同.
GTX1080Ti是更高端的配置.擁有3584個ALU,352位內(nèi)存總線,總內(nèi)存帶寬484GB/s,88個ROP和224個紋理單元;而GTX1080只有2560,256位,320GB/s和160.GTX1080Ti擁有6個GPC,也就是說6個光柵引擎;而GTX1080只有4個.4個GPC是和GTX1080相同的,而多出來的2個GPC每個只包含4個TPC.GTX1080Ti使用了120億個晶體管,而GTX1080只采用了72億個.Pascal架構(gòu)的靈活之處在于可以縮小規(guī)模.比如GTX1070是GTX1080減去了一個GPC,而GTX1050包含了兩個GPC,每個GPC包含3個SM.
23.10.3 案例學(xué)習(xí):AMD GCN Vega
AMD Graphics Core Next(GCN)架構(gòu)備用與許多AMD產(chǎn)品和Xbox One以及PlayStation4.在這里我們描述GCN Vega架構(gòu)的一般元素,是這些游戲機使用的架構(gòu)的進(jìn)化.
GCN架構(gòu)的核心構(gòu)件塊是計算單元(compute unit,CU),如圖所示.CU擁有4個SIMD單元,每個SIMD單元擁有16個SIMD通道,也就是16個一致的ALU.每個SIMD單元能夠執(zhí)行64線程的指令,這稱為一個wavefront.每個時鐘周期每個SIMD單元能執(zhí)行一個單精度浮點指令.由于GCN架構(gòu)每個SIMD單元執(zhí)行一個wavefront的64線程,所以需要4個時鐘周期才能將一個wavefront處理完畢(16通道并行,4個周期執(zhí)行完).注意一個CU能同時執(zhí)行來自不同核(kernel)的代碼.由于每個SIMD單元擁有16通道并且每個時鐘周期執(zhí)行一個指令,每個CU的最大吞吐量是4個SIMD *16SIMD通道=64單精度浮點運算(每個時鐘周期).CU也能在不需要高精度時,執(zhí)行兩倍的半精度浮點(16位浮點數(shù))指令.比如機器學(xué)習(xí)和著色器計算.注意兩個半精度浮點數(shù)值會被打包進(jìn)一個單精度浮點寄存器.每個SIMD單元擁有64kB的寄存器文件大小,因為一個單精度浮點數(shù)需要4B,每個wavefront64線程,所以每個線程有個單精度浮點數(shù)寄存器.ALU擁有四個硬件管線階段.
每個CU擁有指令緩存(圖里沒畫)被4個SIMD單元共享.相關(guān)指令被提交到SIMD單元的指令緩沖(instruction buffer,IB).每個IB擁有能處理10個wavefront的容量,便于使SIMD單元切入和切出來隱藏延遲.這意味著CU能處理40個wavefront,也就相當(dāng)于個線程,所以圖中的CU調(diào)度器能同時處理2560個線程,它的工作就是為CU中的不同單元分配任務(wù).每個時鐘周期,CU會考慮其中所有的wavefronts的指令問題,然后為每個執(zhí)行端口(execution port)分配至多一條指令.CU的執(zhí)行端口包括分支,標(biāo)量/向量ALU,標(biāo)量/向量內(nèi)存,局部數(shù)據(jù)共享,全局?jǐn)?shù)據(jù)共享或?qū)С?以及特殊指令;也就是說,每個執(zhí)行端口大致映射到CU的一個單元上.
標(biāo)量單元是64位ALU,也在SIMD單元之間共享.它自身擁有專屬的標(biāo)量RF(寄存器文件)和標(biāo)量數(shù)據(jù)緩存(沒畫).標(biāo)量RF擁有800個32位寄存器為每個SIMD單元,也就是共有大小.執(zhí)行與wavefront緊密耦合.因為需要4個時鐘周期向SIMD單元完全發(fā)布一個指令,所以標(biāo)量單元只能每4個時鐘周期為特定SIMD單元服務(wù).標(biāo)量單元處理控制流,指針運算和其他可以在一個warp中線程間共享的運算.條件和非條件分支指令由標(biāo)量單元發(fā)出,在分支和消息單元(branch and message unit)中執(zhí)行.每個SIMD單元擁有一個48位程序計數(shù)器(program counter,PC),被所有通道共享.一個PC已經(jīng)足夠,因為所有通道執(zhí)行相同的指令.對于采取的分支,PC會更新.被此單元發(fā)送的消息包括debug消息,特殊圖形同步消息和CPU中斷.
Vega10架構(gòu)如圖所示.最上面的部分包括一個圖形命令處理器(graphics command processor),2個硬件調(diào)度器(HWS)和8個同步計算引擎(asynchronous compute engine,ACE).GPC的工作是向GPU的圖形管線和計算引擎分發(fā)圖形任務(wù).HWS的緩沖以隊列方式工作,并盡快分配給給ACE.ACE的工作是為計算引擎調(diào)度計算任務(wù).Vega10有兩個DMA引擎負(fù)責(zé)處理拷貝任務(wù)(圖里沒畫).GPC,ACE和DMA引擎能以并行的方式工作并且為GPU提交工作,這樣可以提高利用率,因為任務(wù)可以在不同的隊列中交錯進(jìn)行.工作能從任何隊列中分發(fā)出去,不需要等待其它工作完成,這意味著計算引擎能夠同時執(zhí)行多個獨立任務(wù).ACE通過緩存或內(nèi)存同步.它們一起支持任務(wù)圖(task graph),所以一個ACE的任務(wù)可以依靠另一個ACE的任務(wù)或者圖形管線上的任務(wù).推薦將更小的計算和拷貝任務(wù)與更大的圖形任務(wù)交錯進(jìn)行.
圖中可以看到,一共有4個圖形管線(graphics pipeline)和4個計算引擎(compute engine).每個計算引擎擁有16個CU,總共64個CU.圖形管線有兩個塊一個叫圖形引擎(graphics engine)一個叫繪制流分片器(draw-stream binning rasterizer,DSBR).圖形引擎擁有一個幾何裝配器(geometry assembler),細(xì)分單元(tessellation unit)和頂點裝配器(vertex assembler).另外,還支持一個新的圖元著色器(primitive shader).圖元著色器的設(shè)計想法是為了更靈活的幾何處理和更快的圖元剔除(primitive culling).DSBR結(jié)合了sort-middle和sort-last架構(gòu)的優(yōu)點,也是tiled緩沖的目的.屏幕空間的圖像被分割為tile,經(jīng)過幾何處理后,每個圖元都被分配給了與它們重疊的tile.在光柵化一個tile的過程中,所有數(shù)據(jù)(如tile buffer)需要保存在L2緩存中,這樣可以提高性能表現(xiàn).像素著色會自動延遲直到tile中的所有幾何體都被處理完畢.于是z-prepass在后臺完成,像素著色只進(jìn)行一次.延遲著色能夠開啟或關(guān)閉,如透明幾何體就需要關(guān)閉延遲著色.
為了處理深度緩沖,模板緩沖和顏色緩沖,GCN架構(gòu)擁有一個塊稱為顏色和深度塊(color and depth block,CDB).他們處理顏色,深度和模板緩沖的讀和寫,還有顏色混合.一個CDB能使用23.5節(jié)的一般方法壓縮顏色緩沖.增量壓縮技術(shù)(delta compression technique),每個tile儲存一個未壓縮的像素顏色,其余顏色值會編碼為這個像素顏色相關(guān)的值.為了提高效率,tile的大小能夠通過訪問不同的模式而動態(tài)的選擇.對于一個原來存儲需要256B的tile,最大壓縮率是8:1,也就是壓縮完32B.在后續(xù)pass中壓縮的顏色能用作紋理顏色,這種情況下紋理單元會解壓這些壓縮的tile,這種做法節(jié)省了帶寬.
光柵化器每個時鐘周期能夠光柵化至多4個圖元.而與圖形管線和計算引擎相連的CDB,每個時鐘周期能寫入16像素.這也就是說,小于16像素的三角形會降低效率.光柵化器也處理粗糙深度測試(HiZ)和層級模板測試.用于HiZ的緩沖稱為HTILE并且是可編程的,比如將遮擋信息反饋給GPU.
Vega的緩存層級如圖所示.層級的最上層(圖中的最右側(cè))的是寄存器,然后是L1和L2緩存.然后是高帶寬內(nèi)存2(high-bandwidth memory2,HBM2)位置也在圖形卡上,最終系統(tǒng)內(nèi)存位置在CPU的一方.Vega的一個新特性是高帶寬緩存控制器(High-Bandwidth Cache Controller,HBCC)在上圖的最下面.它能夠允許顯存能表現(xiàn)得像末級緩存(last-level cache,LLC).意思是如果要進(jìn)行內(nèi)存訪問并且對應(yīng)的內(nèi)容不在顯存中,比如HBM2,那么HBCC會自動從相關(guān)的系統(tǒng)緩存中取出并通過PCIe放入到顯存中,結(jié)果是顯存中很少被用到的頁可能被交換出去.HBM2和系統(tǒng)內(nèi)存之間共享的內(nèi)存池被稱為HBCC內(nèi)存段(HBCC memory segment,HMS).所有圖形塊也是通過L2緩存訪問內(nèi)存的,這和之前的架構(gòu)不同.Vega架構(gòu)同時支持虛擬內(nèi)存.
注意到所有on-chip的塊,如HBCC,XDMA(CrossFire DMA),PCI express,顯示引擎(display engine)和多媒體引擎(multimedia engine),通過一個互連的Infinity Fabric(IF)通信.AMD的CPU也能夠和IF相連,IF可以連接不同芯片模具上的塊.IF也是相關(guān)的,這意味著所有塊能夠看到相同的內(nèi)存內(nèi)容視圖.
Vega架構(gòu)的基礎(chǔ)時鐘頻率是1677MHz,也就是說,峰值計算能力為
其中,2是融合乘加經(jīng)常被當(dāng)作兩個浮點數(shù)運算,然后我們除了來將MFLOPS轉(zhuǎn)換成TFLOPS.這個架構(gòu)靈活而且可拓展.期待看到更多的配置.
23.11 光線追蹤架構(gòu)
這章簡單介紹光線追蹤硬件.我們不會在這個話題上列出所有的最近的引用,但是會指路文章供讀者自行了解.這個領(lǐng)域的研究是2002年開始的,那時的關(guān)注重點是遍歷和交叉,著色是通過固定功能的單元計算的.這個工作后來被Woop等人研究,他提出了一個帶有可編程著色器的架構(gòu).
最近幾年光線追蹤架構(gòu)的議題獲得了越來越多的經(jīng)濟上的興趣.這能通過一些公司如Imagination Technologies,LG Electronics和Samsung都發(fā)布了他們各自的實時光線追蹤的硬件架構(gòu)中看到.然而在本書寫作時只有Imagination Technologies發(fā)布了商業(yè)產(chǎn)品.
這些架構(gòu)有一些共同的特點.首先他們使用了基于AABB的層級體積包圍盒.第二,他們傾向于通過減少ray/box相交檢測的精度來降低硬件復(fù)雜度.最后,他們使用可編程核心以支持可編程著色器,這在當(dāng)今或多或少是必需的.例如Imagination Technologies拓展它們原來的芯片設(shè)計,比如增加了一個能利用著色器核心來著色的光線追蹤單元.光線追蹤單元包含一個光線相交處理器和一個相干性引擎(coherency engine),相干性引擎負(fù)責(zé)的是將具有相似屬性的光線收集起來并且共同處理來實現(xiàn)局部性以達(dá)到更快的光線追蹤.Imagination Technologies的架構(gòu)也包含一個用于構(gòu)件BVH的專用單元.
該領(lǐng)域的研究還在很多方面繼續(xù).包括在便捷遍歷上降低精度,BVH的壓縮表現(xiàn),以及省電.毫無疑問很多的工作需要搞定.
深入閱讀和資源
Akeley,Hanrahan,Hwu,Kirk的計算機圖形架構(gòu)的課程筆記是非常好的資源.Hwu和Kirk寫的書也是CUDA編程和GPU編程很好的資源.每年的High-Performance Graphics和SIGGRAPH會議也提供了最新架構(gòu)特性的學(xué)習(xí)資源.Giesen的trip down the graphics pipeline是非常棒的在線資源,對于想要研究GPU的更多細(xì)節(jié)的人.我們也推薦感興趣的讀者閱讀Hennessy和Patterson的書了解內(nèi)存系統(tǒng).關(guān)于移動端渲染的信息在各個資源之間非常分散,GPU Pro 5這本書中的七篇關(guān)于移動端渲染技術(shù)的文章值得注意.