CUDA架構(gòu)

CUDA是一種新的操作GPU計(jì)算的硬件和軟件架構(gòu),它將GPU視作一個數(shù)據(jù)并行計(jì)算設(shè)備,而且無需把這些計(jì)算映射到圖形API。

1. 硬件架構(gòu)


1.1 GPU困境

雖然GPU通過圖形應(yīng)用程序的算法存在如下幾個特征:算法密集、高度并行、控制簡單、分多個階段執(zhí)行以及前饋(Feed
Forward)流水線等,能夠在高度密集型的并行計(jì)算上獲得較高的性能和速度,但在2007年以前GPU要實(shí)現(xiàn)這樣的應(yīng)用還是存在許多困難的:

  1. GPU只能通過一個圖形的API來編程,這不僅加重了學(xué)習(xí)負(fù)擔(dān)更造成那些非圖像應(yīng)用程序處理這些 API 的額外開銷。
  2. 由于DRAM內(nèi)存帶寬,一些程序會遇到瓶頸。
  3. 無法在 DRAM 上進(jìn)行通用寫操作。
    所以NVIDIA于2006年11月在G80系列中引入的Tesla統(tǒng)一圖形和計(jì)算架構(gòu)擴(kuò)展了GPU,使其超越了圖形領(lǐng)域。通過擴(kuò)展處理器和存儲器分區(qū)的數(shù)量,其強(qiáng)大的多線程處理器陣列已經(jīng)成為高效的統(tǒng)一計(jì)算平臺,同時適用于圖形和通用并行計(jì)算應(yīng)用程序。從G80系列開始NVIDIA加入了對CUDA的支持。

1.2 芯片結(jié)構(gòu)

具有Tesla架構(gòu)的GPU是具有芯片共享存儲器的一組SIMT(單指令多線程)多處理器。它以一個可伸縮的多線程流處理器(Streaming Multiprocessors,SMs)陣列為中心實(shí)現(xiàn)了MIMD(多指令多數(shù)據(jù))的異步并行機(jī)制,其中每個多處理器包含多個標(biāo)量處理器(Scalar Processor,SP),為了管理運(yùn)行各種不同程序的數(shù)百個線程,SIMT架構(gòu)的多處理器會將各線程映射到一個標(biāo)量處理器核心,各標(biāo)量線程使用自己的指令地址和寄存器狀態(tài)獨(dú)立執(zhí)行。

GPU的共享存儲器的SIMT多處理器模型.png

如上圖所示,每個多處理器(Multiprocessor)都有一個屬于以下四種類型之一的芯片存儲器:

  • 每個處理器上有一組本地 32 位寄存器(Registers);
  • 并行數(shù)據(jù)緩存或共享存儲器(Shared Memory),由所有標(biāo)量處理器核心共享,共享存儲器空間就位于此處;
  • 只讀固定緩存(Constant Cache),由所有標(biāo)量處理器核心共享,可加速從固定存儲器空間進(jìn)行的讀取操作(這是設(shè)備存儲器的一個只讀區(qū)域);
  • 一個只讀紋理緩存(Texture Cache),由所有標(biāo)量處理器核心共享,加速從紋理存儲器空間進(jìn)行的讀取操作(這是設(shè)備存儲器的一個只讀區(qū)域),每個多處理器都會通過實(shí)現(xiàn)不同尋址模型和數(shù)據(jù)過濾的紋理單元訪問紋理緩存。
    多處理器 SIMT單元以32個并行線程為一組來創(chuàng)建、管理、調(diào)度和執(zhí)行線程,這樣的線程組稱為 warp 塊(束),即以線程束為調(diào)度單位,但只有所有32個線程都在諸如內(nèi)存讀取這樣的操作時,它們就會被掛起,如圖7所示的狀態(tài)變化。當(dāng)主機(jī)CPU上的CUDA程序調(diào)用內(nèi)核網(wǎng)格時,網(wǎng)格的塊將被枚舉并分發(fā)到具有可用執(zhí)行容量的多處理器;SIMT單元會選擇一個已準(zhǔn)備好執(zhí)行的 warp 塊,并將下一條指令發(fā)送到該 warp塊的活動線程。一個線程塊的線程在一個多處理器上并發(fā)執(zhí)行,在線程塊終止時,將在空閑多處理器上啟動新塊。
    CPU五種狀態(tài)的轉(zhuǎn)換.png
線程束調(diào)度變化.png

2. 軟件架構(gòu)


CUDA是一種新的操作GPU計(jì)算的硬件和軟件架構(gòu),它將GPU視作一個數(shù)據(jù)并行計(jì)算設(shè)備,而且無需把這些計(jì)算映射到圖形API。操作系統(tǒng)的多任務(wù)機(jī)制可以同時管理CUDA訪問GPU和圖形程序的運(yùn)行庫,其計(jì)算特性支持利用CUDA直觀地編寫GPU核心程序。目前Tesla架構(gòu)具有在筆記本電腦、臺式機(jī)、工作站和服務(wù)器上的廣泛可用性,配以C/C++語言的編程環(huán)境和CUDA軟件,使這種架構(gòu)得以成為最優(yōu)秀的超級計(jì)算平臺。


CUDA軟件層次結(jié)構(gòu).png

CUDA在軟件方面組成有:一個CUDA庫、一個應(yīng)用程序編程接口(API)及其運(yùn)行庫(Runtime)、兩個較高級別的通用數(shù)學(xué)庫,即CUFFT和CUBLAS。CUDA改進(jìn)了DRAM的讀寫靈活性,使得GPU與CPU的機(jī)制相吻合。另一方面,CUDA提供了片上(on-chip)共享內(nèi)存,使得線程之間可以共享數(shù)據(jù)。應(yīng)用程序可以利用共享內(nèi)存來減少DRAM的數(shù)據(jù)傳送,更少的依賴DRAM的內(nèi)存帶寬。

3. 編程模型


CUDA程序構(gòu)架分為兩部分:Host和Device。一般而言,Host指的是CPU,Device指的是GPU。在CUDA程序構(gòu)架中,主程序還是由CPU 來執(zhí)行,而當(dāng)遇到數(shù)據(jù)并行處理的部分,CUDA 就會將程序編譯成 GPU能執(zhí)行的程序,并傳送到GPU。而這個程序在CUDA里稱做核(kernel)。CUDA允許程序員定義稱為核的C語言函數(shù),從而擴(kuò)展了C語言,在調(diào)用此類函數(shù)時,它將由N個不同的CUDA線程并行執(zhí)行N次,這與普通的C語言函數(shù)只執(zhí)行一次的方式不同。執(zhí)行核的每個線程都會被分配一個獨(dú)特的線程ID,可通過內(nèi)置的threadIdx變量在內(nèi)核中訪問此ID。在 CUDA 程序中,主程序在調(diào)用任何 GPU內(nèi)核之前,必須對核進(jìn)行執(zhí)行配置,即確定線程塊數(shù)和每個線程塊中的線程數(shù)以及共享內(nèi)存大小。

3.1 線程層次結(jié)構(gòu)

在GPU中要執(zhí)行的線程,根據(jù)最有效的數(shù)據(jù)共享來創(chuàng)建塊(Block),其類型有一維、二維或三維。在同一個塊內(nèi)的線程可彼此協(xié)作,通過一些共享存儲器來共享數(shù)據(jù),并同步其執(zhí)行來協(xié)調(diào)存儲器訪問。一個塊中的所有線程都必須位于同一個處理器核心中。因而,一個處理器核心的有限存儲器資源制約了每個塊的線程數(shù)量。在早起的NVIDIA 架構(gòu)中,一個線程塊最多可以包含 512個線程,而在后期出現(xiàn)的一些設(shè)備中則最多可支持1024個線程。一般 GPGPU程序線程數(shù)目是很多的,所以不能把所有的線程都塞到同一個塊里。但一個內(nèi)核可由多個大小相同的線程塊同時執(zhí)行,因而線程總數(shù)應(yīng)等于每個塊的線程數(shù)乘以塊的數(shù)量。這些同樣維度和大小的塊將組織為一個一維或二維線程塊網(wǎng)格(Grid)。具體框架如圖9所示。

線程塊網(wǎng)格.png


核函數(shù)只能在主機(jī)端調(diào)用,其調(diào)用形式為:Kernel<<<Dg,Db, Ns, S>>>(paramlist)

  • Dg:用于定義整個grid的維度和尺寸,即一個grid有多少個block。為dim3類型。Dim3
    Dg(Dg.x, Dg.y,
    1)表示grid中每行有Dg.x個block,每列有Dg.y個block,第三維恒為1(目前一個核函數(shù)只有一個grid)。整個grid中共有Dg.x*Dg.y個block,其中Dg.x和Dg.y最大值為65535。

  • Db:用于定義一個block的維度和尺寸,即一個block有多少個thread。為dim3類型。Dim3
    Db(Db.x, Db.y,
    Db.z)表示整個block中每行有Db.x個thread,每列有Db.y個thread,高度為Db.z。Db.x和Db.y最大值為512,Db.z最大值為62。
    一個block中共有Db.x*Db.y*Db.z個thread。計(jì)算能力為1.0,1.1的硬件該乘積的最大值為768,計(jì)算能力為1.2,1.3的硬件支持的最大值為1024。

  • Ns:是一個可選參數(shù),用于設(shè)置每個block除了靜態(tài)分配的shared
    Memory以外,最多能動態(tài)分配的shared
    memory大小,單位為byte。不需要動態(tài)分配時該值為0或省略不寫。

  • S:是一個cudaStream_t類型的可選參數(shù),初始值為零,表示該核函數(shù)處在哪個流之中。
    如下是一個CUDA簡單的求和程序:


    CUDA求和程序.png

3.2 存儲器層次結(jié)構(gòu)

CUDA設(shè)備擁有多個獨(dú)立的存儲空間,其中包括:全局存儲器、本地存儲器、共享存儲器、常量存儲器、紋理存儲器和寄存器,如圖
11所示。


CUDA設(shè)備上的存儲器.png

CUDA線程可在執(zhí)行過程中訪問多個存儲器空間的數(shù)據(jù),如圖 12所示其中:

  • 每個線程都有一個私有的本地存儲器。
  • 每個線程塊都有一個共享存儲器,該存儲器對于塊內(nèi)的所有線程都是可見的,并且與塊具有相同的生命周期。
  • 所有線程都可訪問相同的全局存儲器。
  • 此外還有兩個只讀的存儲器空間,可由所有線程訪問,這兩個空間是常量存儲器空間和紋理存儲器空間。全局、固定和紋理存儲器空間經(jīng)過優(yōu)化,適于不同的存儲器用途。紋理存儲器也為某些特殊的數(shù)據(jù)格式提供了不同的尋址模式以及數(shù)據(jù)過濾,方便
    Host對流數(shù)據(jù)的快速存取。
    存儲器的應(yīng)用層次.png

3.3 主機(jī)(Host)和設(shè)備(Device)

如圖 13所示,CUDA假設(shè)線程可在物理上獨(dú)立的設(shè)備上執(zhí)行,此類設(shè)備作為運(yùn)行C語言程序的主機(jī)的協(xié)處理器操作。內(nèi)核在GPU上執(zhí)行,而C語言程序的其他部分在CPU上執(zhí)行(即串行代碼在主機(jī)上執(zhí)行,而并行代碼在設(shè)備上執(zhí)行)。此外,CUDA還假設(shè)主機(jī)和設(shè)備均維護(hù)自己的DRAM,分別稱為主機(jī)存儲器和設(shè)備存儲器。因而,一個程序通過調(diào)用CUDA運(yùn)行庫來管理對內(nèi)核可見的全局、固定和紋理存儲器空間。這種管理包括設(shè)備存儲器的分配和取消分配,還包括主機(jī)和設(shè)備存儲器之間的數(shù)據(jù)傳輸。

CUDA異構(gòu)編程模型.png

  1. CUDA軟硬件

4.1 CUDA術(shù)語

由于CUDA中存在許多概念和術(shù)語,諸如SM、block、SP等多個概念不容易理解,將其與CPU的一些概念進(jìn)行比較,如下表所示。

CPU GPU 層次
算術(shù)邏輯和控制單元 流處理器(SM) 硬件
算術(shù)單元 批量處理器(SP) 硬件
進(jìn)程 Block 軟件
線程 thread 軟件
調(diào)度單位 Warp 軟件
NVIDIA 630顯卡CUDA信息.png

4.2 硬件利用率

當(dāng)為一個GPU分配一個內(nèi)核函數(shù),我們關(guān)心的是如何才能充分利用GPU的計(jì)算能力,但由于不同的硬件有不同的計(jì)算能力,SM一次最多能容納的線程數(shù)也不盡相同,SM一次最多能容納的線程數(shù)量主要與底層硬件的計(jì)算能力有關(guān),如下表顯示了在不同的計(jì)算能力的設(shè)備上,每個線程塊上開啟不同數(shù)量的線程時設(shè)備的利用率。

計(jì)算能力 每個線 程塊的線程數(shù) 1.0 1.1 1.2 1.3 2.0 2.1 3.0
64 67 67 50 50 33 33 50
96 100 100 75 75 50 50 75
128 100 100 100 100 67 67 100
192 100 100 94 94 100 100 94
256 100 100 100 100 100 100 100
…… ……
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,363評論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,497評論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,305評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,962評論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,727評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,193評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,411評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,945評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,777評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,978評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,216評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,657評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,960評論 2 373

推薦閱讀更多精彩內(nèi)容

  • 1. CPU vs. GPU 1.1 四種計(jì)算機(jī)模型 GPU設(shè)計(jì)的初衷就是為了減輕CPU計(jì)算的負(fù)載,將一部分圖形計(jì)...
    王偵閱讀 20,968評論 3 20
  • CUDA從入門到精通(零):寫在前面 本文原版鏈接: 在老板的要求下,本博主從2012年上高性能計(jì)算課程開始接觸C...
    Pitfalls閱讀 3,636評論 1 3
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,782評論 18 139
  • 前言 《并行編程》系列是學(xué)習(xí)《Intro to Parallel Programming》過程中所做的筆記記錄以及...
    葉俊賢閱讀 6,838評論 0 7
  • 你。晨鐘暮鼓訴衷腸。星光下,也把冷月望。
    如云兒閱讀 192評論 0 0