CUDA架構(gòu)

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

1. 硬件架構(gòu)


1.1 GPU困境

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

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

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

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

GPU的共享存儲(chǔ)器的SIMT多處理器模型.png

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

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

2. 軟件架構(gòu)


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


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

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

3. 編程模型


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

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

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

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


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

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

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

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

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


    CUDA求和程序.png

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

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


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

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

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

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

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

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

  1. CUDA軟硬件

4.1 CUDA術(shù)語(yǔ)

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

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

4.2 硬件利用率

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

計(jì)算能力 每個(gè)線 程塊的線程數(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)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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