從硬件層面說起:
上圖是采納了Turing架構的TU102 GPU,它的特點如下:
-
6 GPC(圖形處理簇)
-
36 TPC(紋理處理簇)
-
72 SM(流多處理器)
-
每個GPC有6個TPC,每個TPC有2個SM
-
4,608 CUDA核
-
72 RT核
-
576 Tensor核
-
288 紋理單元
-
12x32位 GDDR6內存控制器 (共384位)
單個SM的結構圖如下:
每個SM包含:
- 64 CUDA核
- 8 Tensor核
- 256 KB寄存器文件
重要概念:
Turing總體架構:TU102為例: 6個Graphics Processing Clusters(圖形處理集群 -GPCs)(每個圖形處理集群包含一個專用光柵引擎和6個TPC)> 36個Texture Processing Clusters(紋理處理集群-TPCs)(每個紋理處理集群包含2個SM)> 72個SM
SM(streaming multiprocessor):
1.Turing架構引入了新的SM體系架構。每個TPC包含2個SM,每個SM包含64個fp32核心和64個int32核心,這使得Turing可以並行執行fp32和int32運算。每個SM還包含8個混合精度的tensor core。
2.Turing的SM被划分為4個進程塊,每個進程塊包含16個fp32核心、16個int32核心、2個Tensor Cores、一個線程束調度器和一個調度單元,每個進程塊還包含一個新的L0指令緩存和一個64KB寄存器。這4個進程塊共享一個可自配置的96KB大小L1/共享內存區域。
3.Turing還改造了核心執行路徑,相比之前的單一執行路徑,Turing在執行混合fp算術指令如FADD、FMAD時為每個CUDA核心增加了另一個並行執行單元來並行執行整數運算和浮點數運算。
4.SM中的每個Tensor Core可以在每個時鍾周期內執行高達64次fp16輸入融合浮點乘加運算(FMA),8個Tensor Core這可以在每個時鍾周期內執行總計512次fp16乘加運算,或1024次fp運算。Turing新引入的INT8精度模式在每個時鍾周期內更是可以執行2048個整數運算。Tesla T4身為Turing第一個使用Turing架構的GPU,包含2560個CUDA核心和320個Tensor Cores,可實現130 TOPs(Tera Operations per second)的int8運算和高達260 TOPs的int4運算。
從軟件層面說起:
對於CUDA的軟件架構我們在邏輯上分為三個層次結構每個層次結構類型有三個維度(x,y,z),層次結構從小到大依次是Thread(線程),Block(線程塊),Grid(網格)。
如圖所示:相當於把GPU上的計算單元分為若干(2~3)個網格,每個網格包含若干(65535)個線程塊,每個線程塊包含若干(512)個線程。對於thread往右x增加,往下y增加往里z增加。Thread,block,gird的設定是方便程序員進行軟件設計,組織線程的,是CUDA編程上的概念。
Grid,Block,thread都是線程的組織形式,最小的邏輯單位是一個thread,最小的硬件執行單位是thread warp,若干個thread組成一個block,block被加載到SM上運行,多個block組成一個Grid。
總而言之,一個kernel對應一個Grid,該Grid又包含若干個Block,Block內包含若干個thread。Grid跑GPU的時候,可能是獨占一個GPU,也可能是多個kernel並發占用一個GPU。
block是常駐在SM上的,一個SM可能有一個或者多個Block,具體根據資源占用分析。
thread以wrap為單位被SM的scheduler發射到計算單元或者其它單元,如SFU,LD/ST unit執行相關操作,需要等待的wrap會被切出(依然是resident狀態)(上下文的切換),以空出執行單元給其它warps。
軟硬件對應關系:
GPU硬件上的並行性是由SM決定的,GPU中每個SM都被設計成支持數以百計的線程並行計算,並且每個GPU都包含了很多SM,所以GPU支持成百上千的線程並行執行。當一個kernel啟動時,thread會被分配到這些SM中去進行運算。大量的thread可能會被分配到不同的SM,同一個Block的thread必然是在同一個SM中並行(SIMT)執行的。NVIDIA把32個threads組成一個warp(如果1個block中有512個thread也就是說有512/32=16個warp),warp是調度和運行的基本單元,warp中所有thread並行執行相同的指令(其實由於SIMT的特性允許thread有自己的執行路徑這樣會導致各個thread的執行結束時間並不一致,所以CUDA提供了cudaThreadSynchronize()來同步同一個Block的thread以保證在下一步處理之前,所有的thread都到達某個時間點)。一個warp需要占用一個SM運行,多個warp(16個warp)需要輪流進入SM,有SM的硬件warp schedule負責調度。
SIMT和SIMD(單指令多數據):CUDA是一種典型的SIMT架構(單指令多線程),SIMT是NVIDIA提出的GPU概念。兩者都是通過將同樣的指令廣播給多個執行單元來實現並行。一個主要的不同就是SIMD要求所有的數組元素在一個統一的同步組里面同步執行,而SIMT允許線程們(32個)在一個warp中各自獨立執行。
SIMT有三個SIMD沒有的主要特征:1.每個thread擁有自己的指令計數器和地址計數器 2.每個thread擁有自己的狀態寄存器 3.每個thread可以有自己的獨立執行路徑(不同於SIMD32是全部一樣的執行路徑)。
開發過程中程序員老爺們可以通過設定block的屬性來告訴GPU硬件,我有多少個線程,這些線程怎么組織。