機器學習系統與基礎設施

CUDA 核心最佳化(kernel optimization)

GPU 以鎖步(lockstep)的執行緒群一次跑上千條執行緒,因此榨出峰值效能靠的不是高明的數學,而是把機器餵飽:讓每條通道都忙、每筆記憶體交易都裝滿、晶片上的快速記憶體一直保持熱的。手工最佳化一個 CUDA 核心,就是不斷重組運算,直到硬體諸多限制全部對齊,常常要把同一段算術用好幾種寫法重寫,直到效能分析器(profiler)不再抱怨。

核心的調控桿有幾個:佔用率(occupancy,常駐 warp 夠多才能藏住記憶體與指令延遲,但要與每執行緒的暫存器與共享記憶體預算權衡)、記憶體存取合併(coalescing,相鄰執行緒碰相鄰位址,讓一個 warp 的載入塌縮成少數幾筆寬交易)、避開記憶庫衝突(bank conflict)的共享記憶體分塊(tiling),以及把 warp 分歧降到最低。在較新的架構上,矩陣乘法的峰值吞吐還要求用正確的分塊形狀與非同步複製管線,把運算元餵進張量核心(tensor core)。整個工作由效能分析器主導:先判斷你是受限於延遲、頻寬還是發射,再針對那個瓶頸下手。

佔用率高未必是目標——一個吃暫存器、佔用率偏低的核心,若能把更多資料留在晶片上、每執行緒發射更多互不相依的工作,反而可能贏過高佔用率的版本。這門功夫是經驗性的;又因為微架構細節每代硬體都在變,快核心是被重新調優的,而非盲目移植。

佔用率是手段而非目的:真正要極大化的是實際交付的 FLOP/s 或 bytes/s,有時這反而意味著刻意跑更少的 warp。

又称
CUDA 核心調優kernel tuning