Cuda技術革命一瞥
當前在老百姓眼中有關計算機技術的最時髦的詞匯莫過于“多核”了。從前年起,“多核”這個東西就走進了家用的行列,現在購置的計算機基本上都是雙核心或者是四核心的。由于“硅芯片主頻的物理極限已經達到,CPU將來的發(fā)展即將走向多核方向”,得到的結果就是AMD和Intel兩家公司的競爭進入了進一步的白熱化階段。
其實一臺計算機多個計算單元的現象很早就出現了。古代有所謂的“解霸卡”,這是一個專門為視頻解壓處理而設計的處理器,原理基本就是一個為浮點優(yōu)化的CPU。把視頻解壓的工作分給解霸卡,而CPU則留下進行更重要的工作。之后Intel推出了MMX指令集,這種卡旋即消失。后來著名的就是Voodoo卡(以及同時代的各類3D加速卡),這是現代顯卡的雛形。他把浮點計算分離出來,并且直接加入了貼圖和燈光的特性,使得3D游戲開始普及。伴隨著DirectX技術的成熟,就產生了現代顯卡?,F代顯卡指的是支持一定的渲染標準的顯卡,如OpenGL標準、DirectX標準等。通過這種設計,程序員可以方便的通過OpenGL和DirectX接口來編制程序,而不需要考慮具體的硬件類型。這是一個跨時代的突破。
在普通的情況下用顯卡進行渲染,速度要比用普通的CPU計算快上幾千倍,而且圖像大小(像素數)越大,加速的比例就越大。這是顯卡的自身特性造成的。顯卡當中,相當于封裝了成百上千個“核心”,所有的“核心”可以一起處理。由于GPU的計算是一種特殊的計算任務,即所計算的每一個像素之間不需要(或者用方法使它不需要)考慮先后順序,那么如果有了上百萬個線程,就可以讓所有的像素同時渲染,這樣所有的像素就可以在一個像素的時間內計算完成。而實際上在CPU上的運算通常是做了一件才能再做一件,這樣就算有一萬個核心,在前一個結果計算出來之前,其他的線程只能傻傻等待,這就相當于一個核心了,因此CPU多核心的發(fā)展要比GPU慢得多。由于兩者計算的目的不同,造成他們的構架不同。因此顯卡與CPU的計算任務通常是分離的。
實際上,假如你知道你現在的將要做的計算是可以高度并行的密集型計算,那么就應該使用GPU來進行運算。然而一般的顯卡卻沒有這樣的功能,它通常只能處理矩陣、貼圖、采樣等等的已經有實際圖形學意義的問題,而對其他的運算,只能轉換成圖形運算才能進行。利用GPU進行通用目的計算(General Purpose Computing)的想法很早就有了,成熟的產品有GPGPU語言等。我曾經歷盡千辛萬苦編寫了一份在顯卡上進行FFT計算的程序,其代碼量之龐大簡直是駭人聽聞。普通的FFT在150行以內就可以完成,而GPU的FFT計算則需要至少千行(利用GPGPU語言的話代碼量會少很多,但是相對于FFT程序,這個語言產品本身的空間就不?。?。之所以有如此之多的代碼量,是因為需要將各種數據通過一個圖形接口(一般是擴展的OpenGL)發(fā)送到GPU,計算之后,再通過這個圖形接口接收結果。
另外,程序員從娘胎里帶出來的“一根筋”(單線程,算完一個再用結果來算另一個)的思維習慣是非常不容易改變的。除非是像渲染 這種明顯就應該是并行運行的東西,其他的東西找出成熟的并行算法非常困難。這就意味著,多核的潛力還必須得到進一步的開發(fā)。當然有一個簡單的方法就是運行很多的進程,可以以此把CPU塞滿。
原理
nVidia公司一直以來是顯卡界的兩位登峰造極者(nVidia和ATI,后者前些日子與AMD公司合并為AMD&ATI公司) 之中更時尚的一位。2006年11月8日,nVidia拋出了他們的通用目的GPU計算的方案CUDA——Compute Unified Device Architecture 即計算統一的設備架構。這是業(yè)界第一個可以用C語言進行編程的通用目GPU計算解決方案。實際上走在了時間的前頭。
CUDA的原理基本如下:
把 大量的線程(這個概念與一般的不同,他是更輕量級的,更快速的)分布在一個個的“塊”中。每個塊共享一段指令和數據,而塊中的每一個線程只能訪問到本塊的 數據以及外層的共享數據,訪問不到塊之間的數據。外部的驅動程序負責把所有的數據和指令拷貝到塊中,然后所有的線程開始同時運行。當最后一個線程結束后運 行結束。 #p#page_title#e#
這樣,指令也相同,數據也相同,因此既不會有換頁問題,也沒有緩存刷新問題(考慮到實際上GPU是不具備與內存速度不同的緩存的,這個速度的提升是靠多點同時訪問和顯卡版內的超大帶寬得到的——總之就是比那么多個CPU要快啦!囧)。僅僅這樣,我們就可以得到前所未有的強大速度提升,這靠的是無以倫比的超大線程數!
在編程方面,如果我們想向一個塊中寫入指令,只需要像C/C++一樣編寫一個函數,然后用CUDA的簡寫方法進行調用(可以自由設置塊數和線程數)。之后CUDA編譯器nvcc自動將代碼編譯成CPU代碼和GPU代碼,并讓GPU代碼可以自動的發(fā)送到適當的快中。期間的一切硬件問題程序員都不需要管,結果就是寫一個CUDA程序和寫一個普通的C程序一樣方便。
我現在的顯卡的參數是這樣的(不是什么高端的顯卡,每個人的顯卡都有類似的能力):14個多核處理器,每個多核理器112個核心,每個核心65536*65536*1個格點(這個不能達到最大值。實際使用中取決于顯卡的當前狀態(tài)),每個格點有512*512*64塊,每塊同時可以運行512個線程(同時每塊具有8k個寄存器)??梢源致杂嬎阋幌?,就算我們只用到了一個格點,我們就可以得到85億個線程。這就是說只要我們的顯存(才十億字節(jié))足夠,那么我們就可以想開多少個線程就開多少個線程。
根據官方發(fā)布的資料,如果是更高端的Tesla卡的話,可以每秒進行500G次浮點運算。CPU浮點運算平均大約消耗400周期的話,那么CPU每秒可以進行2*3G/400=0.15G次浮點運算。相比之下大約能快3000倍左右。但是在這種構架只下,最花費時間的操作不再是運算,而是把指令和數據從內存中拷貝到顯存中的過程?,F在的GPU(PCI-E)帶寬在4G/s左右,這就是我們每毫秒可以把4百萬字節(jié)數據從內存調入到顯卡中,這對于大部分的應用而言可能足夠了,但是如果需要更高端的計算性能,恐怕只有等待顯卡的插槽更新換代了。
應用
我有幸參加了CUDA技術的創(chuàng)始人之一David Kirk博士在清華進行的講座。講座中提到了CUDA從開始到現在不足兩年的時間里的大量應用。實際上有些是令人比較失望的——在一般的狀況下,CUDA的運行速度只達到了CPU的一百倍到一千倍左右,并沒有達到那么夸張的地步——不過這依然足夠改變人們的工作方式了。
- 神經網絡模擬。有一個人建立了一個巨大的神經網絡,用來模擬真實生物的神經活動。眾所周知,每個神經細胞都可以當作是并行運行的,因此這個模型非常適用于CUDA。
- 股票分析軟件。它是以復雜計算為基礎,進行整個美國股市的實時分析的一個軟件。由于股票之間的情況異常復雜,造成經濟學上的公式無法準確預測時間稍微一點的大盤情況。然而,有了CUDA,我們就可以在幾百毫秒之內計算出當前的全美的大盤走勢,這通常將花費數分鐘時間,等我們得到結果之后,它已經沒用了。CUDA讓股票分析軟件從不可能成為了可能。
- 分子流體模擬。這是中科院物理所的一位老師做的。他就是把分子的范德化力(其模型相對復雜)考慮進去。他制作了一個包含幾億個分子水滴,然后進行 模擬。由于每個水滴之間的范德華力只在周圍的范圍內有效,因此可以把每個分子的受力狀況看做是不相干的或弱相干的。這也很適于CUDA。
- 地震研究與模擬。地震研究方面的一個重要問題就是如何快速的處理地震數據。這讓我想起了當時MRI剛被發(fā)明的時候,雖然有了實驗數據,但是算不出結果來。動用了當時最先進的軍用超級計算機才得到一張圖像?,F在的醫(yī)學器械里,MRI是太常見的東西了。這說明將來我們有可能處理更多的地震數據,解開地震規(guī)律之謎。
展望
CUDA是一項以提高計算性能為目的的新興技術,但是其影響將遠遠超出“計算”的范圍。GPGPU是一個神奇的事物,因為如果處理得好的話,那么可以幾千倍的打破摩爾定律,而跳躍到下一個時代。GPGPU的問題就在于編程的痛苦性太高,而 #p#page_title#e#CUDA就是為此目的而設計。就如同David Kirk所言,計算性能提高十倍會使現在的工具變得很方便,計算性能提高一百倍會使現在的軟件更新換代。而計算性能提高一千倍,則會徹底改變人們的工作方式。曾經不可能的慢慢變?yōu)榭赡?。我們期待?span lang="EN-US">CUDA技術以及未來的新的GPGPU技術能夠帶領我們(程序員和用戶)走向新的時代!