流式多處理器(Stream Multi-processor,SM)是構建整個 GPU的核心模塊(執行整個 Kernel Grid),一個流式多處理器上一般同時運行多個線程塊。每個流式多處理器可以視為具有較小結構的CPU,支持指令并行(多發射)。流式多處理器是線程塊的運行載體,但一般不支持亂序執行。每個流式多處理器上的單個Warp以SIMD方式執行相同指令。
圖 3-1 流式多處理器在GPU架構中的位置(以NVIDIA Tesla架構為例,修改自NVIDIA)
3.1 整體微架構
圖 3-3是流式多處理器(SM,AMD稱之為計算單元)微架構(根據公開文獻和專利信息綜合獲得)。
流式多處理器按照流水線可以分為SIMT前端和SIMD后端。整個流水線處理劃分為六個階段,包括取指、譯碼、發射、操作數傳送、執行與寫回。
圖 3-2 GPGPU的流式多處理器結構劃分
SIMD即單指令多數據,采用一個控制器來控制多組計算單元(或處理器),同時對一組數據(向量)中的每一個數據分別執行相同的操作從而實現空間并行性計算的技術。
SIMT即單指令多線程,多個線程對不同的數據集執行相同指令。SIMT的的優勢在于無須把數據整理為合適的矢量長度,并且SIMT允許每個線程有不同的邏輯分支。
按照軟件級別,SIMT層面,流式多處理器由線程塊組成,每個線程塊由多個線程束組成;SIMD層面,每個線程束內部在同一時間執行相同指令,對應不同數據,由統一的線程束調度器(Warp scheduler)調度。
一般意義上的CUDA核,對應于流處理器(SP),以計算單元和分發端口為主組成。
線程塊調度程序將線程塊分派給 SIMT 前端,線程在流式多處理器上以Warp為單位并行執行。
圖 3-3 GPGPU的流式多處理器微架構
流式多處理器中的主要模塊包括:
取指單元(I-Fetch):負責將指令請求發送到指令緩存。并將程序計數器 (PC)指向下一條指令。
指令緩存(I-Cache):如來自取指單元的請求在指令緩存中被命中,則將指令傳送給譯碼單元,否則把請求保存在未命中狀態保持寄存器(MSHR)中。
譯碼單元(Decode):將指令解碼并轉發至I-Buffer。該單元還將源和目標寄存器信息轉發到記分牌,并將指令類型、目標地址(用于分支)和其他控制流相關信息轉發到 SIMT 堆棧。
SIMT 堆棧(SIMT Stack):SIMT堆棧負責管理控制流相關的指令和提供下一程序計數器相關的信息。
記分牌(Scoreboard):用于支持指令級并行。并行執行多條獨立指令時,由記分牌跟蹤掛起的寄存器寫入狀態避免重復寫入。
指令緩沖(I-Buffer):保存所有Warp中解碼后的指令信息。Warp 的循環調度策略決定了指令發射到執行和寫回階段的順序。
后端執行單元:后端執行單元包括CUDA核心(相當于ALU)、特殊功能函數、LD/ST單元、張量核心(Tensor core)。特殊功能單元的數量通常比較少,計算相對復雜且執行速度較慢。(例如,正弦、余弦、倒數、平方根)。
共享存儲:除了寄存器文件,流式多處理器也有共享存儲,用于保存線程塊不同線程經常使用的公共數據,以減少對全局內存的訪問頻率。
3.2 取指與譯碼
圖 3-4 GPU執行流程(修改自 GPGPU-Sim)
取指-譯碼-執行,是處理器運行指令所遵循的一般周期性操作。
取指一般是指按照當前存儲在程序計數器(Program Counter,PC)中的存儲地址,取出下一條指令,并存儲到指令寄存器中的過程。在取指操作結束時,PC 指向將在下一個周期讀取的下一條指令。
譯碼一般是指將存儲在指令寄存器中的指令解釋為傳輸給執行單元的一系列控制信號。
圖 3-5 取指譯碼結構
在GPGPU中,譯碼之后要對指令進行調度,以保證后繼執行單元的充分利用。這一調度通過線程束調度器(Warp Scheduler)實現。
線程束是為了提高效率打包的線程集合(NVIDIA稱之為Warps,AMD稱為Wavefronts)。在每一個循環中的調度單位是Warp,同一個Warp內每個線程在同一時刻執行相同命令。
取指與譯碼操作過程如下:
取指模塊(I-Fetch)根據PC指向的指令,從內存中獲取到相應的指令塊。需要注意的是,在GPGPU中,一般沒有CPU中常見的亂序執行。
圖 3-5 取指模塊
-
指令緩存(I-Cache)讀取固定數量的字節(對齊),并將指令位存儲到寄存器中。
-
對I-Cache的請求會導致命中、未命中或保留失敗(Reservation fail)。保留失敗發生于未命中保持寄存器 (MSHR) 已滿或指令緩存中沒有可替換的區塊。不管命中或者未命中,循環取指都會移向下一Warp。
在命中的情況下,獲取的指令被發送到譯碼階段。在未命中的情況下,指令緩存將生成請求。當接收到未命中響應時,新的指令塊被加載到指令緩存中,然后Warp再次訪問指令緩存。
-
指令緩沖(I-Buffer)用于從I-Cache中獲取指令后對譯碼后的指令進行緩沖。最近獲取的指令被譯碼器譯碼并存儲在 I-Buffer 中的相應條目中,等待發射。
-
每個 Warp 都至少對應兩個 I-Buffer。每個 I-Buffer 條目都有一個有效位(Valid)、就緒位(Ready)和一個存于此 Warp 的已解碼的指令。有效位表示在 I-Buffer 中的該已解碼的指令還未發射,而就緒位則表示該Warp的已解碼的指令已準備好發射到執行流水線。
圖 3-4 指令緩沖
當Warp內的I-Buffer 為空時,Warp以循環順序訪問指令緩存。(默認情況下,會獲取兩條連續的指令)這時對應指令在I-Buffer中的有效位被激活,直到該Warp的所有提取的指令都被發送到執行流水線。
當所有線程都已執行,且沒有任何未完成的存儲或對本地寄存器的掛起寫入,則 Warp 完成執行且不再取指。當線程塊中的所有Warp都執行完成且沒有掛起的操作,標記線程塊完成。所有線程塊完成標記為內核已完成。
相對于CPU,GPU的前端一般沒有亂序發射,每個核心的尺寸就可以更小,算力更密集。
3.3 發射
發射是指令就緒后,從指令緩沖進入到執行單元的過程。
在(譯碼后的)指令發射階段,指令循環仲裁選擇一個Warp,將I-Buffer中的發射到流水線的后級,且每個周期可從同一Warp發射多條指令。
所發射的有效指令應符合以下條件:
- 在Warp里未被設置為屏障等待狀態;
- 在I-Buffer中已被設置為有效指令(有效位被置為1);
- 已通過計分板(Scoreboard)檢查;
- 指令流水線的操作數訪問階段處于有效狀態。
在GPU中,不同的線程束的不同指令,經由SIMT堆棧和線程束調度,選擇合適的就緒的指令發射。
在發射階段,存儲相關指令(Load、Store等)被發送至存儲流水線進行相關存儲操作。其他指令被發送至后級SP(流處理器)進行相關計算。
-
cpu
+關注
關注
68文章
10854瀏覽量
211590 -
gpu
+關注
關注
28文章
4729瀏覽量
128892 -
多處理器
+關注
關注
0文章
22瀏覽量
8920
發布評論請先 登錄
相關推薦
評論