1. 程式人生 > >【GPU程式設計系列之一】從深度學習選擇什麼樣的gpu來談談gpu的硬體架構

【GPU程式設計系列之一】從深度學習選擇什麼樣的gpu來談談gpu的硬體架構

轉自:http://chenrudan.github.io/blog/2015/12/20/introductionofgpuhardware.html

從深度學習在2012年大放異彩,gpu計算也走入了人們的視線之中,它使得大規模計算神經網路成為可能。人們可以通過07年推出的CUDA(Compute Unified Device Architecture)用程式碼來控制gpu進行平行計算。本文首先根據顯示卡一些引數來推薦何種情況下選擇何種gpu顯示卡,然後談談跟cuda程式設計比較相關的硬體架構。

(2016年6月27日更新)Real心塞,最近出了基於PASCAL架構的GTX1070[6]/1080[7],這價效比簡直逆天了…啥980/980ti都不用買了…買一塊Titan X還不如買兩塊1080…

(原文如下)

1.選擇怎樣的GPU型號

這幾年主要有AMD和NVIDIA在做顯示卡,到目前為止,NVIDIA公司推出過的GeForce系列卡就有幾百張[1],雖然不少都已經被淘汰了,但如何選擇適合的卡來做演算法也是一個值得思考的問題,Tim Dettmers[2]的文章給出了很多有用的建議,根據自己的理解和使用經歷(其實只用過GTX 970…)我也給出一些建議。

1

圖1 GPU選擇

上面並沒有考慮筆記本的顯示卡,做演算法加速的話還是選桌上型電腦的比較好。價效比最高的我覺得是GTX 980ti,從引數或者一些使用者測評來看,效能並沒有輸給TITAN X多少,但價格卻便宜不少。從圖1可以看出,價位差不多的顯示卡都會有自己擅長的地方,根據自己的需求選擇即可。要處理的資料量比較小就選擇頻率高的,要處理的資料量大就選視訊記憶體大core數比較多的,有double的精度要求就最好選擇kepler架構的。tesla的M40是專門為深度學習製作的,如果只有深度學習的訓練,這張卡雖然貴,企業或者機構購買還是比較合適的(百度的深度學習研究院就用的這一款[3]),相對於K40單精度浮點運算效能是4.29Tflops,M40可以達到7Tflops。QUADRO系列比較少被人提起,它的M6000價格比K80還貴,效能引數上也並沒有好多少。

在挑選的時候要注意的幾個引數是處理器核心(core)、工作頻率、視訊記憶體位寬、單卡or雙卡。有的人覺得位寬最重要,也有人覺得核心數量最重要,我覺得對深度學習計算而言處理器核心數和視訊記憶體大小比較重要。這些引數越多越高是好,但是程式相應的也要寫好,如果無法讓所有的core都工作,資源就被浪費了。而且在購入顯示卡的時候,如果一臺主機插多張顯示卡,要注意電源的選擇。

2.一些常見的名稱含義

上面聊過了選擇什麼樣的gpu,這一部分介紹一些常見名詞。隨著一代一代的顯示卡效能的更新,從硬體設計上或者命名方式上有很多的變化與更新,其中比較常見的有以下一些內容。

  • gpu架構:Tesla、Fermi、Kepler、Maxwell、Pascal
  • 晶片型號:GT200、GK210、GM104、GF104等
  • 顯示卡系列:GeForce、Quadro、Tesla
  • GeForce顯示卡型號:G/GS、GT、GTS、GTX

gpu架構指的是硬體的設計方式,例如流處理器簇中有多少個core、是否有L1 or L2快取、是否有雙精度計算單元等等。每一代的架構是一種思想,如何去更好完成並行的思想,而晶片就是對上述思想的實現,晶片型號GT200中第二個字母代表是哪一代架構,有時會有100和200代的晶片,它們基本設計思路是跟這一代的架構一致,只是在細節上做了一些改變,例如GK210比GK110的暫存器就多一倍。有時候一張顯卡里面可能有兩張晶片,Tesla k80用了兩塊GK210晶片。這裡第一代的gpu架構的命名也是Tesla,但現在基本已經沒有這種設計的卡了,下文如果提到了會用Tesla架構和Tesla系列來進行區分。

而顯示卡系列在本質上並沒有什麼區別,只是NVIDIA希望區分成三種選擇,GeFore用於家庭娛樂,Quadro用於工作站,而Tesla系列用於伺服器。Tesla的k型號卡為了高效能科學計算而設計,比較突出的優點是雙精度浮點運算能力高並且支援ECC記憶體,但是雙精度能力好在深度學習訓練上並沒有什麼卵用,所以Tesla系列又推出了M型號來做專門的訓練深度學習網路的顯示卡。需要注意的是Tesla系列沒有顯示輸出介面,它專注於資料計算而不是圖形顯示。

最後一個GeForce的顯示卡型號是不同的硬體定製,越往後效能越好,時鐘頻率越高視訊記憶體越大,即G/GS<GT<GTS<GTX。

3.gpu的部分硬體

這一部分以下面的GM204硬體圖做例子介紹一下GPU的幾個主要硬體(圖片可以點選檢視大圖,不想圖片佔太多篇幅)[4]。這塊晶片它是隨著GTX 980和970一起出現的。一般而言,gpu的架構的不同體現在流處理器簇的不同設計上(從Fermi架構開始加入了L1、L2快取硬體),其他的結構大體上相似。主要包括主機介面(host interface)、複製引擎(copy engine)、流處理器簇(Streaming Multiprocessors)、圖形處理簇GPC(graphics processing clusters)、記憶體等等。

1

圖2 GM204晶片結構

主機介面,它連線了gpu卡和PCI Express,它主要的功能是讀取程式指令並分配到對應的硬體單元,例如某塊程式如果在進行記憶體複製,那麼主機介面會將任務分配到複製引擎上。

複製引擎(圖中沒有表示出來),它完成gpu記憶體和cpu記憶體之間的複製傳遞。當gpu上有複製引擎時,複製的過程是可以與核函式的計算同步進行的。隨著gpu卡的效能變得強勁,現在深度學習的瓶頸已經不在計算速度慢,而是資料的讀入,如何合理的呼叫複製引擎是一個值得思考的問題。

流處理器簇SM是gpu最核心的部分,這個翻譯參考的是GPU程式設計指南,SM由一系列硬體組成,包括warp排程器、暫存器、Core、共享記憶體等。它的設計和個數決定了gpu的計算能力,一個SM有多個core,每個core上執行執行緒,core是實現具體計算的處理器,如果core多同時能夠執行的執行緒就多,但是並不是說core越多計算速度一定更快,最重要的是讓core全部處於工作狀態,而不是空閒。不同的架構可能對它命名不同,kepler叫SMX,maxwell叫SMM,實際上都是SM。而GPC只是將幾個sm組合起來,在做圖形顯示時有排程,一般在寫gpu程式不需要考慮這個東西,只要掌握SM的結構合理的分配SM的工作即可。

圖中的記憶體控制器控制的是L2記憶體,每個大小為512KB。

4.流處理器簇的結構

上面介紹的是gpu的整個硬體結構,這一部分專門針對流處理器簇SM來分析它內部的構造是怎樣的。首先要明白的是,gpu的設計是為了執行大量簡單任務,不像cpu需要處理的是複雜的任務,gpu面對的問題能夠分解成很多可同時獨立解決的部分,在程式碼層面就是很多個執行緒同時執行相同的程式碼,所以它相應的設計了大量的簡單處理器,也就是stream process,在這些處理器上進行整形、浮點型的運算。下圖給出了GK110的SM結構圖。它屬於kepler架構,與之前的架構比較大的不同是加入了雙精度浮點運算單元,即圖中的DP Unit。所以用kepler架構的顯示卡進行雙精度計算是比較好的。

1

圖2 GK110的SMX結構圖

上面提到過的一個SM有多個core或者叫流處理器,它是gpu的運算單元,做整形、浮點型計算。可以認為在一個core上一次執行一個執行緒,GK110的一個SM有192個core,因此一次可以同時執行192個執行緒。core的內部結構可以檢視[5],實現演算法一般不會深究到core的結構層面。SFU是特殊函式單元,用來計算log/exp/sin/cos等。DL/ST是指Load/Store,它在讀寫執行緒執行所需的全域性記憶體、區域性記憶體等。

一個SM有192個core,8個SM有1536個core,這麼多的執行緒並行執行需要有統一的管理,假如gpu每次在1536個core上執行相同的指令,而需要計算這一指令的執行緒不足1536個,那麼就有core空閒,這對資源就是浪費,因此不能對所有的core做統一的排程,從而設計了warp(執行緒束)排程器。32個執行緒一組稱為執行緒束,32個執行緒一組執行相同的指令,其中的每個thread稱為lane。一個執行緒束接受同一個指令,裡面的32個執行緒同時執行,不同的執行緒束可執行不同指令,那麼就不會出現大量執行緒空閒的問題了。但是線上程束排程上還是存在一些問題,假如某段程式碼中有if…else…,在排程一整個執行緒束32個執行緒的時候不可能做到給thread0~15分配分支1的指令,給thread16~31分配分支2的指令(實際上gpu對分支的控制是,所有該執行分支1的執行緒執行完再輪到該執行分支2的執行緒執行),它們獲得的都是一樣的指令,所以如果thread16~31是在分支2中它們就需要等待thread0~15一起完成分支1中的計算之後,再獲得分支2的指令,而這個過程中,thread0~15又在等待thread16~31的工作完成,從而導致了執行緒空閒資源浪費。(2016/07/18更新:此處理解有點問題,感謝intijk同學指出來)因此在真正的排程中,是半個warp執行相同指令,即16個執行緒執行相同指令,那麼給thread0~15分配分支1的指令,給thread16~31分配分支2的指令,那麼一個warp就能夠同時執行兩個分支。而從kepler架構開始,一個Warp Scheduler就集成了兩個dispatch,這兩個dispatch能夠同時給同一個warp分配兩個不同的獨立的指令,如下圖所示,從而可以讓一個warp同時執行兩個分支的指令。

1

圖3 Warp Scheduler排程圖(圖來源[8])

另外一個比較重要的結構是共享記憶體shared memory。它儲存的內容在一個block(暫時認為是比執行緒束32還要大的一些執行緒個數集合)中共享,一個block中的執行緒都可以訪問這塊記憶體,它的讀寫速度比全域性記憶體要快,所以執行緒之間需要通訊或者重複訪問的資料往往都會放在這個地方。在kepler架構中,一共有64kb的空間大小,供共享記憶體和L1快取分配,共享記憶體實際上也可看成是L1快取,只是它能夠被使用者控制。假如共享記憶體佔48kb那麼L1快取就佔16kb等。在maxwell架構中共享記憶體和L1快取分開了,共享記憶體大小是96kb。而暫存器的讀寫速度又比共享記憶體要快,數量也非常多,像GK110有65536個。

此外,每一個SM都設定了獨立訪問全域性記憶體、常量記憶體的匯流排。常量記憶體並不是一塊記憶體硬體,而是全域性記憶體的一種虛擬形式,它跟全域性記憶體不同的是能夠快取記憶體和線上程束中廣播資料,因此在SM中有一塊常量記憶體的快取,用於快取常量記憶體。

5.小結

本文談了談gpu的一些重要的硬體組成,就深度學習而言,我覺得對記憶體的需求還是比較大的,core多也並不是能夠全部用上,但現在開源的庫實在完整,想做卷積運算有cudnn,想做卷積神經網路caffe、torch,想做rnn有mxnet、tensorflow等等,這些庫內部對gpu的呼叫做的非常好並不需使用者操心,但瞭解gpu的一些內部結構也是很有意思的。

另,一開始接觸GPU並不知道是做圖形渲染的…所以有些地方可能理解有誤,主要基於計算來討論GPU的構造。

參考: