一、常用術語
Task:任務。可以完整得到結果的一個程序,一個程序段或若干個程序段。例如搬磚。
Parallel Task:並行任務。可以並行計算的任務。多個人搬磚。
Serial Execution:串行執行。一個人搬磚。
Parallel Execution:並行執行。多個人一起搬磚。
Shared Memory:共享存儲。
Distributed Memory:分布式存儲。磚放在不同的地方。
Communications:通信。幾個人搬磚時互相安排下一次搬幾個磚。
Synchronization:同步。若干個人一起拿磚、一起放磚,動作同步。
Granularity:粒度。任務划分時,任務的大小。
Observed Speedup:加速比。對比一個標志物,並行系統所能獲得的性能提升。
Parallel Overhead:並行開銷。
Scalability:可擴展性。並行數擴展后,性能是否線性提升,主要要注意並行通信等的開銷問題。
二、Amdahl's Law並行加速比
如果有N個處理器並行處理:
$$\begin{aligned} speedup &=\frac{1}{\frac{P}{N}+S} \end{aligned}$$
並行化的可擴展性存在極限,主要取決於不能並行的部分(串行部分):
三、GPU
FLOPS:Floating-point Operations Per Second ,每秒浮點運算操作數量
GFLOPS:One billion FlOPs,每秒十億次浮點運算
TFLOPS:1000 GFLOPs,每秒萬億次浮點運算
在CPU-style核心中:
左邊是主要進行計算的部分(干活),右邊主要是為了讓任務完成得更快而產生了一系列管理部件(占據了芯片的很大部分成本和面積)。
GPU結構的進化過程:
1.在GPU核心中,為其進行了瘦身,大量縮減了右邊的管理機構,得到瘦身后的核,並使用多個核:
將這樣的理念更深入的實現,就可以得到可以大量並行化的核:
這一系列並行核芯可以同時執行多個程序片元(即程序段),這些程序片元需要共享相同的指令流。因為如果不是相同的指令流,則需要很復雜的控制機構,那就變成了CPU style了。
(上述概念相當於增加了干活的人)
2.我們可以增加核的數量,那我們也可以加寬核(增加每個核的ALU數):
在這個核中,我們就可以進行向量的運算(多個數據組成向量vector)。
(上述概念相當於增加了一個人可以同時處理的數據個數,一個人8把切西瓜的刀,一次切8個西瓜)
3.如何處理指令流中有分支的情況:
例如當x>0時,執行操作A,當x<0時,執行操作B:
如圖,8個ALU執行同一個指令流,但是其中有3個的數據大於0,執行A操作。而剩下5個數據小於0,執行B操作。此時,A和B操作只能錯開來執行,不能同時執行。那么這就會導致ALU存在一個性能的最壞情況,白白浪費。
4.停滯stalls的問題:
當核心要處理的數據還沒准備好時(處理很快,數據訪問速度慢),或者對其他任務的結果有依賴。則需要停滯下來進行等待,這樣很浪費性能。
我們可以通過使用大量的獨立片元相互切換來使核心一直有事情做。
如上圖所示,當任務1沒准備好時,就去做任務2,2沒准備好就做任務3......
在切換這些任務的過程中,需要保存每次運行的上下文信息,所以每個核心都有一個叫上下文存儲池的存儲空間。
將存儲空間分塊:
空間划分數量多,則可以切換的任務數多,但每個任務所能存放的上下文就比較小。反之任務數少,每個任務存放上下文多。
(上下文切換可以是軟件管理的也可以是硬件管理的,還可以是兩者結合的,例如GPU主要是硬件管理的,而且上下文非常多)
5.FLOPS計算
如上圖所示:
1). 16個核心cores
2). 每個核心8個計算單元ALUs,一共128個ALUs,即16核心 X 8個ALUs = 128
3). 16核就可以承載16路指令流
4). 每個核可以存儲4個任務的上下文,則可以同時跑64路的指令流,即16核 X 4任務 = 64
5). 總的可以承載512個程序片元,即64個指令流 X 每核8個ALUs = 512
6).FLOPS 為256GFLOPS, 16核 X 8 ALUs X 1GHz X 2 = 256GFLOPS(為什么要乘以2)
6.GPU設計總結(工人階級的血汗史)
1).使用瘦身的核,來增加並行處理數
2).每個核中塞N個ALUs
3).讓其不停的干活,即任務切換
7.物理GPU的設計
NVIDIA GeForce GTX 480采用Fermi架構:
有480個SP(stream processors)流處理器,實際上就是ALUs。取名也叫CUDA core。
15個核心,這個核心叫SM,即流多處理器,Stream multiprocessor。
每個SM有兩組,每組16個CUDA core,即32個ALUs。15 X 32 = 480。
GTX680:
每個SM中有192個CUDA cores(圖中淺綠色部分)。SM更強,改名為SMX。
192個CUDA,但是每32個CUDA core作為一組,則需要6個組長,但實際上只有4個組長,這就需要動態的調度(具體調度方法不做了解)。
整個GTX680芯片由8個SMX組成。
8.顯存
GPU芯片的很大部分面積都是CUDA core,而顯存放在芯片的外面。
最重要的是訪存帶寬,因為CPU的運算是很快的,但是讀寫存儲中的數據可能是很慢的。雖然目前GPU中的訪存帶寬做了專門的設計和優化,但對於GPU的運算能力來說還是不太夠。但就算這樣也比CPU快很多倍。
GPU中緩存的大小相對CPU更小,因為GPU的訪存帶寬比CPU大,所以處理好帶寬的利用就好了。
減少帶寬需求:
1).盡量減少數據的訪問。
2).小數據打包訪存,減少訪存的次數。
9.高效的GPU任務具備的條件
1).具有成千上萬的獨立工作,盡量利用大量的ALU單元,大量的片元切換來掩藏延遲。
2).可以共享指令流,使用與SIMD處理。
3).最好是計算密集的任務,通信和計算開銷比例合適,不要受制於訪存帶寬。