Nvidia CUDA初級教程4 GPU體系架構概述
視頻:https://www.bilibili.com/video/BV1kx411m7Fk?p=5
講師:周斌
本節內容:
- 為什么需要GPU
- 三種方法提升GPU的處理速度
- 實際GPU的設計舉例:
- NVDIA GTX 480: Fermi
- NVDIA GTX 680: Kepler
- GPU存儲器設計
名詞解釋
- FLOPS - Floating-point OPerations per Second
- GFLOPS - One billion (10e9) FLOPS
- TFLOPS - 1000GFLOPS
為什么需要GPU
- 應用的需求越來越高
- 計算機技術由應用驅動 Application Driven
- 石油勘探
- 氣象預報
- …
GPU圖示
結構略圖
GPU是一個異構的多處理器芯片,為圖形圖像處理優化
執行單元 Execute Shader
CPU類型的內核
可以看到,在常規的CPU類型的芯片中,真正進行運算的部分(左側)所占的面積并不大,而是大緩存和上節提到的亂序執行控制邏輯、分支預測器等優化部分占了很大一部分面積。
思路1:精簡、減肥
移除掉那些來幫助單個指令流執行的更快的組件。
兩個核,同時執行兩個程序片元
16個核,同時執行16個程序片元
指令流共享:多個程序片元共享指令流。因為如果要執行不同的指令流的話,就需要復雜的控制機構。
思路二:增加ALU,SIMD
- 處理單元ALU改進
- 指令變化
- 多數據并行
128(16*8)個程序片元同時執行,并發16路指令流
這16路可以共享相同的指令流,也可以不共享。
注意:
- SIMD處理并不總是需要顯式的SIMD指令:
- 選項一:顯式的向量運算指令
- SSE等
- 選項二:標量指令,但是硬件進行矢量化
- 硬件進行指令流共享
- NVIDIA等架構
- 多個片元共享指令流
- 選項一:顯式的向量運算指令
分支處理怎么辦?
由于共享相同的指令流,故按照根據邏輯,某些數據在分支被執行時,另一些在其他分支的數據只能等待。因為它們共享指令流,同一時間必須做相同的事情。
停滯怎么辦?
指令有時需要等待其依賴的數據
思路三:片元切換,掩藏延遲
上面提到,很多時候(如分支處理、停滯等),會出現大量片元等待的情況,這無疑會大大降低效率。對此,我們有思路三:
- 大量的獨立片元相互切換
- 通過偏遠切換來掩藏延遲
給單個片元設置多個(彼此獨立的)任務,當某個任務停滯時,去執行其他任務。
獲得較高的吞吐 throughput。
上下文存儲空間
18個小的上下文:更好的延遲掩藏的效果
12個中等大小的上下文
四個大的上下文:延遲隱藏效果較差
每個上下文更大,但是延遲隱藏能力較差
注意:
- 上下文切換可以使軟件管理也可以是硬件管理,也可以是結合管理。
總結
“我”的設計
根據上面的三個思路,我們得到了一種芯片設計:
- 16個核
- 每個核8個乘加ALU
- 16個同時指令流
- 64路并發指令流
- 512 (16*4*8) 個并發程序片元
- 256GFLOPS,1GHz
三個關鍵思路
- 保留每個核的計算部分,將其他部分盡量移除
- 將每個核填滿 ALU (通過共享指令流)
- 選項1:顯式的 SIMD 向量指令
- 選項2:隱式的共享,由硬件管理
- 通過在多組任務間切換避免停滯
不同GPU架構舉例
Fermi架構
…
Kepler架構
…
存儲和數據訪問
CPU類型的緩存
CPU通常會有多級緩存
GPU型的吞吐處理核
GPU中有更多的ALU,沒有傳統的分級緩存,需要更高的帶寬
帶寬是非常寶貴的資源
減少帶寬需求
- 減少不必要的數據請求,做更多的計算
- 每次訪存多取數據,從而減少訪存次數
現代GPU的存儲器結構
總結
GPU的特點
GPU是異構、眾核的處理器
針對吞吐優化
高效的GPU任務具備的條件
- 具有成千上萬的獨立工作
- 盡量利用大量的ALU單元
- 大量的片元切換掩藏延遲
- 可以共享指令流
- 適用于 SIMD
- 最好是計算密集的任務
- 通信和計算的開銷比例合適
- 不要受制于訪存帶寬