??? GPU的SIMD性能超強(qiáng),比CPU強(qiáng)得太多太多,由此帶來異常強(qiáng)悍的浮點(diǎn)運(yùn)算性能,請看下圖。
??? 畫外音:不知道我的6200A排在什么地方哈哈。
??? 其實(shí)上圖有偏頗,這張圖節(jié)選自Siggraph2004,而現(xiàn)在ATi 1800XT的SIMD性能已經(jīng)超過了6800好多,可不是游戲性能。不過可以看出,比CPU的浮點(diǎn)運(yùn)算性能高好幾倍是不真的事實(shí),可是如何利用呢?
??? 可編程硬件的到來為我們開了一個(gè)好頭,也許未來計(jì)算機(jī)硬件的發(fā)展趨勢就是,通用計(jì)算Generic Computing(GC,自造詞匯,可不是垃圾收集)。顯卡一直以來都是和Pixel打交道,讀取Texel,處理Primitive,寫入FrameBuffer,為SIMD的應(yīng)用打下了堅(jiān)實(shí)的基礎(chǔ)。顯卡芯片從開始就是并行設(shè)計(jì)的,這樣從紋理單元讀取Texel時(shí)才能發(fā)揮效力,當(dāng)年大名鼎鼎的Riva TNT2的意思其實(shí)是TwiNs Textures雙紋理,而不是黃色炸藥。Geforce3依靠添加的幾個(gè)昂貴的register實(shí)現(xiàn)了Vertex Programming。NV收購3dfx,推出NV30系列芯片,伴隨著DX8為PC機(jī)引入Shader,開創(chuàng)PC機(jī)圖像畫質(zhì)飛躍的先河,如今熱門游戲大多數(shù)已經(jīng)使用可編程著色技術(shù)用來實(shí)現(xiàn)以往在工作站上才能實(shí)現(xiàn)的效果,這就是為什么如今看游戲?qū)崟r(shí)演算的畫面都比當(dāng)年Square動(dòng)用sgi工作站集群渲染出來的FF8動(dòng)畫效果好的原因。其實(shí)高級CG圖形理論在80年代就已經(jīng)相當(dāng)成熟,比如78年的Shadow mapping,White的Ray-tracing等等。那些技術(shù)以后我會(huì)慢慢給大家介紹,大家不妨去NVIDIA下載一個(gè)SDK研究一下,還有MS DX SDK也是必需的。
??? 先說目前可編程硬件用作通用計(jì)算的局限,而且在我看來,這個(gè)局限在Vista與DX10流行后可能依舊得不到解決,那就是API的問題。顯卡廠商提供的驅(qū)動(dòng),無一例外的都是徹底為顯示服務(wù)的,而不是用來標(biāo)榜自己是GPGPU的。雖然說都有了自己的本地編譯器(主要是用于編譯GLSL string codes,HLSL可以預(yù)先編譯好,然后再由驅(qū)動(dòng)載入執(zhí)行),可是依舊不是為了計(jì)算非圖形數(shù)據(jù)服務(wù)。于是找到了Sh。Sh是一個(gè)很有趣的東西,使用了metaprogramming技術(shù),模擬圖形語言的算法,編譯的時(shí)候轉(zhuǎn)化為對應(yīng)的低等級ASM語句,很多Graphic Slide里面進(jìn)行核心算法展示的時(shí)候都用的Sh。有興趣地可以到
這里看一下。強(qiáng)烈建議顯卡廠商推出可以直接進(jìn)行計(jì)算的驅(qū)動(dòng),不要和FrameBuffer牽涉,可以直接通過Bus寫入內(nèi)存,技術(shù)上并不難,也許是個(gè)商業(yè)問題。關(guān)鍵時(shí)刻永遠(yuǎn)是商業(yè)左右技術(shù)的發(fā)展,而不是技術(shù)人員的一廂情愿就可以左右世界發(fā)展,如今已經(jīng)不是工業(yè)革命時(shí)代了。
??? 給大家介紹來自Starford University的
Brook(聽起來好像廣告,不過在Shading Language界可是有Starford Shading Language得一席之地的)。Brook可以理解為是一個(gè)C編譯器,只不過它編譯的不是Bin,而是C++ string codes,而且是著色計(jì)算語句數(shù)組。比如有這樣一段Brook代碼,簡單的Alpha混合,不對,不像,反正就是它了:
kernel?void?saxpy(float?alpha,?float4?x<>,?float4?y<>,
out?float4?result<>)?{
result?=?(alpha?*?x)?+?y;
}
???
??? 編譯成最終的C++代碼變成,
static?const?char*?__saxpy_fp30[]?=?{
"!!FP1.0\n"
"DECLARE?alpha;\n"
"TEX?R0,?f[TEX0].xyxx,?TEX0,?RECT;\n"
"TEX?R1,?f[TEX1].xyxx,?TEX1,?RECT;\n"
"MADR?o[COLR],?alpha.x,?R0,?R1;\n"
"END?\n"
"##!!BRCC\n"
"##narg:4\n"
"##c:1:alpha\n"
"##s:4:x\n"
"##s:4:y\n"
"##o:4:result\n"
"##workspace:1024\n"
"##!!multipleOutputInfo:0:1:\n"
"",NULL};
void?saxpy?(const?float?alpha,const?::brook::stream&?x,const?::brook::stream&?y,
::brook::stream&?result)?{
??? static?const?void?*__saxpy_fp[]?=?{"fp30",?__saxpy_fp30,?"ps20",?__saxpy_ps20,
??? ??? ??? ??? ??? "cpu",?(void?*)?__saxpy_cpu,?NULL,?NULL?};
??? static?__BRTKernel?k(__saxpy_fp);
??? k->PushConstant(alpha);
??? k->PushStream(x);
??? k->PushStream(y);
??? k->PushOutput(result);
??? k->Map();
}
???
??? 這不就是純粹的Shading Language么。不過值得注意的是,Brook通過運(yùn)行庫進(jìn)行封裝,把GPU當(dāng)作Streaming Processor,由CPU進(jìn)行控制,計(jì)算數(shù)據(jù)并輸出。目前似乎只能進(jìn)行圖形的計(jì)算,比如FFT,Ray-Tracing等演示,還沒有到達(dá)能夠計(jì)算pi的程度。
??? 思考了一下。精度問題需要解決,F(xiàn)P16剛剛開始廣泛使用,F(xiàn)P32還不能夠支持硬件過濾。FP32僅僅只是IEEE754 float的精度而已,更本談不上double的精度,用在需要精度較高的地方可能還不是很適合。如我設(shè)想那樣,進(jìn)行pi的幾百萬位的計(jì)算,目前來說不太可能,首先,Shading Language從來就沒有提供地址的操作,也就是無法選澤Pixel的位置,也就是無法對FrameBuffer進(jìn)行準(zhǔn)確定位。如果可以解決這個(gè)問題,那么就可以進(jìn)行真正意義上的通用計(jì)算,那個(gè)時(shí)候FrameBuffer只是一個(gè)暫時(shí)的緩沖容器而已。
??? SIMD的物理計(jì)算可以相當(dāng)?shù)膹?qiáng)悍。物理特性計(jì)算都是強(qiáng)調(diào)同時(shí)性的,而GPU可以同時(shí)并行計(jì)算,充分發(fā)揮了自己的優(yōu)勢,難怪NVIDIA要和Havok進(jìn)行合作。記得以前看過博客園中一位先生寫的物理引擎,著實(shí)震驚,我建議他不妨研究研究這一塊。Stream的概念將在DX10上得到徹底的詮釋,不妨看看我以前翻譯的DX10文章,其中Geometry Shader很有意思。
??? 我期待下一代API出現(xiàn),一個(gè)嶄新的軟硬件組合方案,這樣就可能為Display Adapter這個(gè)古老的東西帶來真正的革命。值得注意的是,AMD已經(jīng)收購了ATi,而Intel還在為100億美元收購NV的價(jià)格評估的時(shí)候,也許下一代變革已經(jīng)開始了,讓我們拭目以待。
??? 提到的東西可以在這里找到
??? Brook
http://sourceforge.net/projects/brook??? libSh
http://sourceforge.net/projects/libsh