1

謝邀~

關(guān)于GPU的并行計(jì)算,我們從三點(diǎn)進(jìn)行簡(jiǎn)單的闡述。

一:什么是GPU

很久以前,大概2000年那時(shí)候,顯卡還被叫做圖形加速卡。一般叫做加速卡的都不是什么核心組件,和現(xiàn)在蘋(píng)果使用的M7協(xié)處理器地位差不多。這種東西就是有了更好,沒(méi)有也不是不行,只要有個(gè)基本的圖形輸出就可以接顯示器了。在那之前,只有一些高端工作站和家用游戲機(jī)上才能見(jiàn)到這種單獨(dú)的圖形處理器。

后來(lái)隨著PC的普及,游戲的發(fā)展和Windows這樣的市場(chǎng)霸主出現(xiàn),簡(jiǎn)化了圖形硬件廠商的工作量,圖形處理器,或者說(shuō)顯卡才逐漸普及起來(lái)。

GPU有非常多的廠商都生產(chǎn),和CPU一樣,生產(chǎn)的廠商比較多,但大家熟悉的卻只有3個(gè),以至于大家以為GPU只有AMD、NVIDIA、Intel3個(gè)生產(chǎn)廠商。

nVidia GPU

AMD GPU

Intel MIC協(xié)處理器

nVidia Tegra 4

AMD ARM服務(wù)器

CUDA C/C++

CUDA fortran

OpenCL

MIC OpenMP

CUDA



二:GPU與CPU的區(qū)別

想要理解GPU與CPU的區(qū)別,需要先明白GPU被設(shè)計(jì)用來(lái)做什么,F(xiàn)代的GPU功能涵蓋了圖形顯示的方方面面,我們只取一個(gè)最簡(jiǎn)單的方向作為例子。

大家可能都見(jiàn)過(guò)上面這張圖,這是老版本Direct X帶的一項(xiàng)測(cè)試,就是一個(gè)旋轉(zhuǎn)的立方體。顯示出一個(gè)這樣的立方體要經(jīng)過(guò)好多步驟,我們先考慮簡(jiǎn)單的,想象一下他是個(gè)線(xiàn)框,沒(méi)有側(cè)面的“X”圖像。再簡(jiǎn)化一點(diǎn),連線(xiàn)都沒(méi)有,就是八個(gè)點(diǎn)(立方體有八個(gè)頂點(diǎn)的)。那么問(wèn)題就簡(jiǎn)化成如何讓這八個(gè)點(diǎn)轉(zhuǎn)起來(lái)。

首先,你在創(chuàng)造這個(gè)立方體的時(shí)候,肯定有八個(gè)頂點(diǎn)的坐標(biāo),坐標(biāo)都是用向量表示的,因而至少也是個(gè)三維向量。然后“旋轉(zhuǎn)”這個(gè)變換,在線(xiàn)性代數(shù)里面是用一個(gè)矩陣來(lái)表示的。向量旋轉(zhuǎn),是用向量乘以這個(gè)矩陣。把這八個(gè)點(diǎn)轉(zhuǎn)一下,就是進(jìn)行八次向量與矩陣的乘法而已。

這種計(jì)算并不復(fù)雜,拆開(kāi)來(lái)看無(wú)非就是幾次乘積加一起,就是計(jì)算量比較大。八個(gè)點(diǎn)就要算八次,2000個(gè)點(diǎn)就要算2000次。這就是GPU工作的一部分,頂點(diǎn)變換,這也是最簡(jiǎn)單的一部分。剩下還有一大堆比這更麻煩的就不說(shuō)了。

總而言之,CPU和GPU因?yàn)樽畛跤脕?lái)處理的任務(wù)就不同,所以設(shè)計(jì)上有不小的區(qū)別。它們分別針對(duì)了兩種不同的應(yīng)用場(chǎng)景。CPU需要很強(qiáng)的通用性來(lái)處理各種不同的數(shù)據(jù)類(lèi)型,同時(shí)又要邏輯判斷又會(huì)引入大量的分支跳轉(zhuǎn)和中斷的處理。這些都使得CPU的內(nèi)部結(jié)構(gòu)異常復(fù)雜。而GPU面對(duì)的則是類(lèi)型高度統(tǒng)一的、相互無(wú)依賴(lài)的大規(guī)模數(shù)據(jù)和不需要被打斷的純凈的計(jì)算環(huán)境。

于是CPU和GPU就呈現(xiàn)出非常不同的架構(gòu)(示意圖):

CPU與GPU區(qū)別大揭秘

圖片來(lái)自nVidia CUDA文檔。其中綠色的是計(jì)算單元,橙紅色的是存儲(chǔ)單元,橙黃色的是控制單元。

GPU采用了數(shù)量眾多的計(jì)算單元和超長(zhǎng)的流水線(xiàn),但只有非常簡(jiǎn)單的控制邏輯并省去了Cache。而CPU不僅被Cache占據(jù)了大量空間,而且還有有復(fù)雜的控制邏輯和諸多優(yōu)化電路,相比之下計(jì)算能力只是CPU很小的一部分。

而GPU的工作大部分就是這樣,計(jì)算量大,但沒(méi)什么技術(shù)含量,而且要重復(fù)很多很多次。就像你有個(gè)工作需要算幾億次一百以?xún)?nèi)加減乘除一樣,最好的辦法就是雇上幾十個(gè)小學(xué)生一起算,一人算一部分,反正這些計(jì)算也沒(méi)什么技術(shù)含量,純粹體力活而已。

而CPU就像老教授,積分微分都會(huì)算,就是工資高,一個(gè)老教授資頂二十個(gè)小學(xué)生,你要是富士康你雇哪個(gè)?GPU就是這樣,用很多簡(jiǎn)單的計(jì)算單元去完成大量的計(jì)算任務(wù),純粹的人海戰(zhàn)術(shù)。這種策略基于一個(gè)前提,就是小學(xué)生A和小學(xué)生B的工作沒(méi)有什么依賴(lài)性,是互相獨(dú)立的。

很多涉及到大量計(jì)算的問(wèn)題基本都有這種特性,比如你說(shuō)的破解密碼,挖礦和很多圖形學(xué)的計(jì)算。這些計(jì)算可以分解為多個(gè)相同的簡(jiǎn)單小任務(wù),每個(gè)任務(wù)就可以分給一個(gè)小學(xué)生去做。

但還有一些任務(wù)涉及到“流”的問(wèn)題。比如你去相親,雙方看著順眼才能繼續(xù)發(fā)展。總不能你這邊還沒(méi)見(jiàn)面呢,那邊找人把證都給領(lǐng)了。這種比較復(fù)雜的問(wèn)題都是CPU來(lái)做的。

而某些任務(wù)和GPU最初用來(lái)解決的問(wèn)題比較相似,所以用GPU來(lái)算了。GPU的運(yùn)算速度取決于雇了多少小學(xué)生,CPU的運(yùn)算速度取決于請(qǐng)了多么厲害的教授。教授處理復(fù)雜任務(wù)的能力是碾壓小學(xué)生的,但是對(duì)于沒(méi)那么復(fù)雜的任務(wù),還是頂不住人多。當(dāng)然現(xiàn)在的GPU也能做一些稍微復(fù)雜的工作了,相當(dāng)于升級(jí)成初中生高中生的水平。但還需要CPU來(lái)把數(shù)據(jù)喂到嘴邊才能開(kāi)始干活,究竟還是靠CPU來(lái)管的。

三:并行計(jì)算

首先我們說(shuō)一下并行計(jì)算的概念,它是一種類(lèi)型的計(jì)算,它的許多計(jì)算或執(zhí)行過(guò)程是同時(shí)進(jìn)行的。將大問(wèn)題可以分成較小的問(wèn)題,然后可以同時(shí)解決。可以同CPU或主機(jī)進(jìn)行協(xié)同處理,擁有自己的內(nèi)存,甚至可以同時(shí)開(kāi)啟1000個(gè)線(xiàn)程。

采用GPU進(jìn)行計(jì)算時(shí)與CPU主要進(jìn)行以下交互:

  1. CPU與GPU之間的數(shù)據(jù)交換
  2. 在GPU上進(jìn)行數(shù)據(jù)交

先說(shuō)明一下,一般來(lái)說(shuō)同一時(shí)刻一個(gè)CPU或GPU計(jì)算核心上(就是我們通常所說(shuō)的“核”)只能夠進(jìn)行一個(gè)運(yùn)算,在超線(xiàn)程技術(shù)中,一個(gè)計(jì)算核心在同一時(shí)刻可能進(jìn)行多個(gè)計(jì)算(比如對(duì)于雙核四線(xiàn)程的CPU,在不發(fā)生資源沖突的情況下,每個(gè)計(jì)算核心可能同時(shí)進(jìn)行兩個(gè)計(jì)算),但超線(xiàn)程通常只是使邏輯計(jì)算核心翻倍。

我們平時(shí)看到自己使用的CPU可以同時(shí)運(yùn)行幾十個(gè)程序,實(shí)際上,從微觀角度來(lái)說(shuō),這幾十個(gè)程序在一定程度上仍然是串行的,比如在四核四線(xiàn)程CPU上,同一時(shí)刻只能夠進(jìn)行4個(gè)運(yùn)算,這幾十個(gè)程序便只能在四個(gè)計(jì)算核心上輪換執(zhí)行,只是由于切換速度很快,在宏觀上表現(xiàn)出的就是這些程序在“同時(shí)”運(yùn)行。

GPU最突出的特點(diǎn)就是:計(jì)算核心多。

CPU的計(jì)算核心一般只有四個(gè)、八個(gè),一般不超過(guò)兩位數(shù),而用于科學(xué)計(jì)算的GPU的計(jì)算核心可能上千個(gè)。正由于計(jì)算核心數(shù)量的巨大優(yōu)勢(shì),GPU在同一時(shí)刻能夠進(jìn)行的計(jì)算的數(shù)量遠(yuǎn)遠(yuǎn)地把CPU比了下去。

這時(shí)候,對(duì)于那些可以并行進(jìn)行的計(jì)算,利用GPU的優(yōu)勢(shì)就能夠極大地提高效率。這里解釋一下任務(wù)的串行計(jì)算和并行計(jì)算。串行計(jì)算通俗來(lái)說(shuō)就是先計(jì)算完一個(gè)之后再計(jì)算下一個(gè),并行計(jì)算則是同時(shí)并行的計(jì)算若干個(gè)。比如計(jì)算實(shí)數(shù)a與向量B=[1 2 3 4]的乘積,串行計(jì)算就是先計(jì)算a*B[1],再計(jì)算a*B[2],然后計(jì)算a*B[3],最后計(jì)算a*B[4],從而得到a*B的結(jié)果,并行計(jì)算就是同時(shí)計(jì)算a*B[1]、a*B[2]、a*B[3]和a*B[4],得到a*B的結(jié)果。

如果只有一個(gè)計(jì)算核心,四個(gè)計(jì)算任務(wù)是不可能并行執(zhí)行的,只能夠一個(gè)一個(gè)地串行計(jì)算,但如果有四個(gè)計(jì)算核心,則可以把四個(gè)獨(dú)立的計(jì)算任務(wù)分到四個(gè)核上并行執(zhí)行,這便是并行計(jì)算的優(yōu)勢(shì)所在。正因如此,GPU的計(jì)算核心多,能夠進(jìn)行并行計(jì)算的規(guī)模便非常大,對(duì)于一些能夠通過(guò)并行計(jì)算解決的計(jì)算問(wèn)題便表現(xiàn)出了優(yōu)于CPU的性能。

比如破譯密碼,將任務(wù)分解成可以獨(dú)立執(zhí)行的若干份,每一份分配在一個(gè)GPU核心上,便可以同時(shí)執(zhí)行多份破譯任務(wù),從而加快破譯速度。

但并行計(jì)算不是萬(wàn)能的,它需要一個(gè)前提:?jiǎn)栴}可以分解為能夠并行執(zhí)行的若干個(gè)部分。很多問(wèn)題不滿(mǎn)足這個(gè)條件,比如一個(gè)問(wèn)題有兩步,而第二步的計(jì)算依賴(lài)于第一步的結(jié)果,此時(shí),這兩部分便不能并行的執(zhí)行,只能夠串行地依次執(zhí)行。實(shí)際上,我們平時(shí)的計(jì)算任務(wù)常常有復(fù)雜的依賴(lài)關(guān)系,很多重要的計(jì)算任務(wù)并不能夠并行化。這是GPU的一個(gè)劣勢(shì)。

關(guān)于GPU編程方面主要有以下方法:

由于不是編程科班出身,這里就不多加介紹了,有興趣的朋友可以自行找資料。關(guān)于GPU的并行計(jì)算,就說(shuō)這么多,有更深了解的朋友歡迎來(lái)溝通。

最佳貢獻(xiàn)者

你的回答

單擊“發(fā)布您的答案”,即表示您同意我們的服務(wù)條款