上一篇提到,GPU optimization 很多時候不只是讓運算本身變快,還要想辦法減少資料搬移。
那要怎麼知道一個程式到底是:
算不夠快,還是資料搬不夠快?
這時候就可以用一個很經典的模型來看:Roofline Model。

image source: https://modal.com/gpu-glossary/perf/roofline-model
這張圖其實沒有看起來那麼複雜,先看懂 X 軸、Y 軸和那個轉折點就差不多了。
X 軸是 Arithmetic Intensity(AI):
Arithmetic Intensity = FLOPs / Bytes
意思就是:
每搬 1 Byte 的資料,可以做多少運算?
如果 AI 很低,代表搬了很多資料,結果只做一點點計算。
搬很多資料
↓
算一下
↓
又要搬資料
反過來,如果同一份資料可以被重複使用很多次:
搬一次資料
↓
算很多次
AI 就會比較高。
所以越往右,可以先理解成:
Data Reuse 越高,搬進來的資料被拿來做更多計算。
這也就是上一篇提到 Shared Memory 時,為什麼一直在講「資料搬進來之後重複使用」。
Y 軸就比較直覺了:
Performance = FLOP/s
也就是 GPU 每秒實際完成多少浮點運算。
越往上,代表效能越高。
所以 Roofline 上的一個點,可以理解成:
這個 workload 的 AI 有多高,以及它實際跑到了多少 FLOP/s。
當 AI 很低的時候,GPU 搬了很多資料,卻沒有多少計算可以做。
這時候就算 GPU 本身有很強的算力也沒用,因為資料根本餵不夠快。
這時效能主要受到 Memory Bandwidth 限制:
Performance = Memory Bandwidth × AI
所以如果 Memory Bandwidth 不變,但 AI 慢慢增加:
AI ↑
→ 每份資料可以做更多計算
→ Performance ↑
這就是為什麼 Roofline 左半邊會是一條往右上方走的斜線。
這個區域叫做:
Memory-bound
也就是:
GPU 不是算不動,而是在等資料。
假設我們一直提高 AI。
理論上,每秒可以做的計算就會一直增加。
但 GPU 本身的算力也是有上限的。
例如一張 GPU 的 Peak Performance 是:
100 TFLOP/s
那不管資料餵得多快,它最多就是只能做到大約 100 TFLOP/s。
所以當效能一路上升,最後碰到 GPU 的 Peak FLOPS 之後,再繼續提高 AI,也不會繼續往上。
這就是 Roofline 上面的水平線。
這個區域叫做:
Compute-bound
這時候 memory 已經餵得夠快了,真正的瓶頸變成:
GPU 就只能算這麼快。
斜線和水平線交會的位置通常叫做 Ridge Point。
它發生在:
Memory Bandwidth × AI = Peak FLOPS
換句話說:
Ridge Point AI = Peak FLOPS / Memory Bandwidth
這個點其實很有意思。
它告訴我們:
這張 GPU 需要多高的 Arithmetic Intensity,才有機會把它的算力全部用完?
而且這個位置不是只看 GPU 有多少 FLOPS,而是同時取決於:
例如 GPU 算力變得更強,但 Memory Bandwidth 沒有一起增加,那就需要更高的 AI,才能把這些運算單元餵飽。