CUDA執行緒層次

yyfn風辰發表於2010-02-01
GPU執行緒以網格(grid)的方式組織,而每個網格中又包含若干個執行緒塊,在G80/GT200系列中,每一個執行緒塊最多可包含512個執行緒,Fermi架構中每個執行緒塊支援高達1536個執行緒。同一執行緒塊中的眾多執行緒擁有相同的指令地址,不僅能夠並行執行,而且能夠通過共享儲存器(Shared memory)和柵欄(barrier)實現塊內通訊。這樣,同一網格內的不同塊之間存在不需要通訊的粗粒度並行,而一個塊內的執行緒之間又形成了允許通訊的細粒度並行。這些就是CUDA的關鍵特性:執行緒按照粗粒度的執行緒塊和細粒度的執行緒兩個層次進行組織、在細粒度並行的層次通過共享儲存器和柵欄同步實現通訊,這就是CUDA的雙層執行緒模型。

在執行時,GPU的任務分配單元(global block scheduler)將網格分配到GPU晶片上。啟動CUDA 核心時,需要將網格資訊從CPU傳輸到GPU。任務分配單元根據這些資訊將塊分配到SM上。任務分配單元使用的是輪詢策略:輪詢檢視SM是否還有足夠的資源來執行新的塊,如果有則給SM分配一個新的塊,如果沒有則檢視下一個SM。決定能否分配的因素有:每個塊使用的共享儲存器數量,每個塊使用的暫存器數量,以及其它的一些限制條件。任務分配單元在SM的任務分配中保持平衡,但是程式設計師可以通過更改塊內執行緒數,每個執行緒使用的暫存器數和共享儲存器數來隱式的控制,從而保證SM之間的任務均衡。任務以這種方式劃分能夠使程式獲得了可擴充套件性:由於每個子問題都能在任意一個SM上執行,CUDA程式在核心數量不同的處理器上都能正常執行,這樣就隱藏了硬體差異。

對於程式設計師來說,他們需要將任務劃分為互不相干的粗粒度子問題(最好是易平行計算),再將每個子問題劃分為能夠使用執行緒處理的問題。

同一執行緒塊中的執行緒開始於相同的指令地址,理論上能夠以不同的分支執行。但實際上,在塊內的分支因為SM構架的原因被大大限制了。核心函式實質上是以塊為單位執行的。同一執行緒塊中的執行緒需要SM中的共享儲存器共享資料,因此它們必須在同一個SM中發射。執行緒塊中的每一個執行緒被髮射到一個SP上。

任務分配單元可以為每個SM分配最多8個塊。而SM中的執行緒排程單元又將分配到的塊進行細分,將其中的執行緒組織成更小的結構,稱為執行緒束(warp)。在CUDA中,warp對程式設計師來說是透明的,它的大小可能會隨著硬體的發展發生變化,在當前版本的CUDA中,每個warp是由32個執行緒組成的。SM中一條指令的延遲最小為4個指令週期。8SP採用了發射一次指令,執行4次的流水線結構。所以由32個執行緒組成的WarpCUDA程式執行的最小單位,並且同一個warp是嚴格序列的,因此在warp內是無須同步的。在一個SM中可能同時有來自不同塊的warp。當一個塊中的warp在進行訪存或者同步等高延遲操作時,另一個塊可以佔用SM中的計算資源。這樣,在SM內就實現了簡單的亂序執行。不同塊之間的執行沒有順序,完全並行。無論是在一次只能處理一個執行緒塊的GPU,還是在一次能處理數十乃至上百個執行緒塊的GPU上,這一模型都能很好的適用。

目前,某一時刻只能有一個核心函式正在執行,但是在Fermi架構中,這一限制已被解除。如果在一個核心訪問資料時,另一個核心能夠進行計算,則可以有效的提高裝置的利用率。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23057064/viewspace-626593/,如需轉載,請註明出處,否則將追究法律責任。

相關文章