GPU不能完全取代CPU的最大原因指的是什么
小編今天帶大家了解GPU不能完全取代CPU的最大原因指的是什么,文中知識(shí)點(diǎn)介紹的非常詳細(xì)。覺(jué)得有幫助的朋友可以跟著小編一起瀏覽文章的內(nèi)容,希望能夠幫助更多想解決這個(gè)問(wèn)題的朋友找到問(wèn)題的答案,下面跟著小編一起深入學(xué)習(xí)“GPU不能完全取代CPU的最大原因指的是什么”的知識(shí)吧。
最近寫(xiě) CUDA 寫(xiě)出精神病,以 NVIDIA GPU 為例分析下
GPU的相比CPU有幾個(gè)特點(diǎn)
運(yùn)算資源非常豐富
控制部件占的面積比較小
內(nèi)存帶寬大,目前獨(dú)顯都采用 GDDR5 顯存,位寬也高,主流獨(dú)顯內(nèi)存帶寬是CPU的十倍(200GB/s 對(duì)比 20GB)
內(nèi)存延遲高,對(duì)比 CPU 使用多級(jí)緩存掩蓋延遲,GPU 采用多線程掩蓋延遲
寄存器資源極為豐富,32bit 寄存器有 64k 個(gè) ,單線程可用 255 個(gè)
所以,GPU 只適合處理分支少,數(shù)據(jù)量大,延遲不敏感的任務(wù)。
先看一個(gè)GTX 1080 (Compute capability 6.1) 的 SM(stream multiprocessor) 結(jié)構(gòu)
<img src="https://pic1.zhimg.com/v2-aa0d4d996dcc374c1a0a4cb25a925630_b.jpg" data-size="small" data-rawwidth="698" data-rawheight="1220" data-default-watermark-src="https://pic2.zhimg.com/v2-00878f4438c2ac6d6c2974e535f07919_b.jpg" class="origin_image zh-lightbox-thumb" width="698" data-original="https://pic1.zhimg.com/v2-aa0d4d996dcc374c1a0a4cb25a925630_r.jpg">
CC 6.0 SM,來(lái)自NVDIA 可以看到,一個(gè) SM 中包含4個(gè) Warp,每個(gè) Warp 含有 32 個(gè) CUDA Core【1】。那么,是不是一個(gè)Warp 就相當(dāng)于 CPU 的 32 核呢?
一、 GPU 不適合處理大量分支
我們上面說(shuō)了,GPU 控制部件面積比較小,為了節(jié)約控制器,32 個(gè) CUDA Core 必須時(shí)刻執(zhí)行同樣的指令。也就是說(shuō),一個(gè) Warp 內(nèi)部的所有 CUDA Core 的 PC(程序計(jì)數(shù)器)一直是同步的【2】,但是訪存地址是可以不同的,每個(gè)核心還可以有自己獨(dú)立的寄存器組,這種執(zhí)行方式叫做 SIMT(Single Instruction Multi Trhead)。
這是,你可能會(huì)問(wèn),如果這一個(gè) Warp 中永遠(yuǎn)都在執(zhí)行相同的指令,如果分支了怎么處理呢?
問(wèn)的好,其實(shí) Warp 中的 CUDA Core 并不是真的永遠(yuǎn)都執(zhí)行相同的指令,它還可以不執(zhí)行啊
<img src="https://pic2.zhimg.com/v2-76c403af291e234075bd93453a7a03dd_b.jpg" data-size="small" data-rawwidth="800" data-rawheight="600" data-default-watermark-src="https://pic1.zhimg.com/v2-eba259420dbe266ec4bfe31e8507916c_b.jpg" class="origin_image zh-lightbox-thumb" width="800" data-original="https://pic2.zhimg.com/v2-76c403af291e234075bd93453a7a03dd_r.jpg">
An example of warp divergence(http://15418.courses.cs.cmu.edu/spring2013/article/11) 這樣會(huì)導(dǎo)致 Warp Divergence(見(jiàn)上圖)。如果極端情況下,每一個(gè)Core的指令流都不一樣,那么甚至還可能導(dǎo)致一個(gè) Warp 中僅有一個(gè) Core 在工作,效率降低為 1/32.
二、GPU 需要數(shù)據(jù)高度對(duì)齊
別看 GPU 一個(gè) Warp 核心這么多,帶寬看起來(lái)這么大,但是實(shí)際上一個(gè)一個(gè) Warp 的內(nèi)存訪問(wèn)是成組的,一次只能讀取連續(xù)的且對(duì)齊的 128byte?!?】(這正好是WarpSize 32 * 4 byte)
<img src="https://pic4.zhimg.com/v2-65c845c668b20978c3a4f1f945d5d107_b.jpg" data-size="normal" data-rawwidth="578" data-rawheight="83" class="origin_image zh-lightbox-thumb" width="578" data-original="https://pic4.zhimg.com/v2-65c845c668b20978c3a4f1f945d5d107_r.jpg">
上圖這種操作的效率是最高的。如果訪問(wèn)完全分散,那么效率可能會(huì)又變成1/32.如下圖。
<img src="https://pic2.zhimg.com/v2-e81cc83a0c305ae35b76be32e469e1a5_b.jpg" data-size="normal" data-rawwidth="599" data-rawheight="93" class="origin_image zh-lightbox-thumb" width="599" data-original="https://pic2.zhimg.com/v2-e81cc83a0c305ae35b76be32e469e1a5_r.jpg">
而且 NVIDIA GPU 的緩存策略和 CPU 也不同,沒(méi)有時(shí)間局部性
DIFFERENCE BETWEEN CPU L1 CACHE AND GPU L1 CACHE
The CPU L1 cache is optimized for both spatial and temporal locality. The GPU L1 cache is designed for spatial but not temporal locality. Frequent access to a cached L1 memory location does not increase the probability that the data will stay in cache.
-- 《Professional CUDA Programming》 你可能又會(huì)問(wèn),CPU 的 Cache line 不也有 64bytes嘛,也就比 GPU 少一半啊,這有什么差別嗎?當(dāng)然有,CPU 是一個(gè)核心一個(gè) L1,GPU 是兩個(gè) Warp 一個(gè) L1 Cache 【4】。 整個(gè)Warp 有一個(gè)核心數(shù)據(jù)沒(méi)準(zhǔn)備好都執(zhí)行不了。
當(dāng)然,這么苛刻的訪存條件,如果真的做 C = A+ B 還是沒(méi)什么問(wèn)題的,現(xiàn)實(shí)中訪存不會(huì)真的這么對(duì)齊,所以NVIDIA也下了很多功夫,準(zhǔn)備了 Cache 和 Shared Memory, Constant Cache 等部件,力求讓程序員能高效訪問(wèn)內(nèi)存。
三、GPU 訪存延遲大
說(shuō)起來(lái)訪存延遲和上一節(jié)的對(duì)齊還是有不少關(guān)系,這里分開(kāi)講。
你可能還注意到,一個(gè) SM(CC6.1) 最多可同時(shí)啟動(dòng) 1024 個(gè)線程,但是一個(gè) SM 中僅有 4個(gè) Warp 共計(jì) 4 * 32 = 128 個(gè) CUDA Core。顯然一個(gè)SM可以啟動(dòng)的線程數(shù)比 CUDA Core 的數(shù)量大好多。這是為什么呢。
我們看下典型的 GPU 訪存延遲(《Professional CUDA Programming》數(shù)據(jù)可能有點(diǎn)老)
10-20 cycles for arithmetic operations
400-800 cycles for global memory accesses 訪存一次能做40個(gè)運(yùn)算啦!但是GPU的顯存帶寬實(shí)際上是非常高的。怎么能讓CudaCore 盡量滿載呢?這時(shí) SIMT 就上場(chǎng)了。
沒(méi)關(guān)系,這個(gè) Warp (這里指32個(gè)線程,之前文中混淆了調(diào)度單位和硬件單位)在等數(shù)據(jù)準(zhǔn)備好,我們可以執(zhí)行另外一組32個(gè)線程嘛,這樣雖然延遲還是很大,但是 CUDA Core 和 Memory 都能夠充分利用。
GPU 的線程切換不同于 CPU ,在 CPU 上切換線程需要保存現(xiàn)場(chǎng),將所有寄存器都存到主存中,而我們最開(kāi)始說(shuō)了,一個(gè) SM 中有高達(dá) 64k 個(gè) (注意不是64kbytes,有些中文書(shū)寫(xiě)錯(cuò)了)4 bytes 寄存器。而每個(gè) Thread 最高使用的寄存器數(shù)量為255。少年你發(fā)現(xiàn)什么了嗎?
256 * 4 * 32 = 32k。也就是說(shuō)我每個(gè)線程把寄存器用到爆,也才用了一半的寄存器,那多出來(lái)的這些寄存器是干啥的?
其實(shí),GPU 的線程切換只是切換了寄存器組,延遲超級(jí)低,幾乎沒(méi)有成本??紤]到通常線程并不會(huì)使用高達(dá)255個(gè)寄存器,實(shí)際上一個(gè) CUDA Core 可以隨時(shí)在八個(gè)線程之間反復(fù)橫跳,那個(gè)線程數(shù)據(jù)準(zhǔn)備好了就執(zhí)行哪個(gè)【5】。這是 GPU 優(yōu)于 CPU 的地方,也是為了掩蓋延遲沒(méi)辦法的事情。
總而言之,GPU 訪存還是需要對(duì)齊,而且延遲還是很大,但是最大吞吐量 (在場(chǎng)景合適的情況下,一個(gè)比較長(zhǎng)的單位時(shí)間,處理的數(shù)據(jù)量)是遠(yuǎn)高于 CPU 的。
【注1】LD/SD 是存取部件,用來(lái)訪問(wèn)顯存,SFU 為超越函數(shù)單元
【注2】 Volta 架構(gòu)重大更新,目前允許每個(gè)線程有單獨(dú)PC
【注3】經(jīng)過(guò) L1 Cache 的數(shù)據(jù)讀取是以 128 byte 為單元,還可以配置為不經(jīng)過(guò)緩存,單元大小為32byte,寫(xiě)入操作單元大小可以為為 32,64,128 bytes,本條說(shuō)的都是 Global Memory access。
【注4】NVIDIA GPU 的 Cache 最近幾代架構(gòu)變化明顯,具體架構(gòu)請(qǐng)具體分析
【注5】實(shí)際上線程切換是以 Warp 為單位
感謝大家的閱讀,以上就是“GPU不能完全取代CPU的最大原因指的是什么”的全部?jī)?nèi)容了,學(xué)會(huì)的朋友趕緊操作起來(lái)吧。相信億速云小編一定會(huì)給大家?guī)?lái)更優(yōu)質(zhì)的文章。謝謝大家對(duì)億速云網(wǎng)站的支持!