Roofline 模型(roofline model)
/ ROOF-line /
你買了一輛飛快的跑車,卻老是開著它穿過一個只有一座窄橋、人人都得過的小鎮。過了某個點,更快的引擎買不到任何東西——決定車流多快的是橋,不是引擎。Roofline 模型是一幅簡單而誠實的圖,為電腦回答同一個問題:我的程式是被「晶片做算術的速度」所限,還是被「它從記憶體搬資料的速度」所限?它把兩個限制畫在同一張圖上,讓你看出哪一個是你的橋。
這就是那張圖。橫軸是算術強度(arithmetic intensity)——程式每從記憶體搬一位元組資料,做多少次算術運算(每位元組的運算數)。縱軸是可達成的效能(每秒運算數)。兩道天花板構成屋頂的形狀。從左邊升起的斜天花板是記憶體限制:效能等於記憶體頻寬乘以算術強度,所以在低強度時你受頻寬所限,把算術加寬沒有幫助。右邊平坦的天花板是運算限制:機器的尖峰算術速率,無論你重用多少資料都無法超越。斜線與平線相交之處是「脊點」(ridge point)——你必須達到的強度,才能不再被記憶體餓著。
誠實地說為什麼這要緊。一個程式的算術強度告訴你身處哪個區域。低強度(每位元組少數運算,像把兩個大陣列相加,讀 8 位元組才做 1 個加法)坐在斜屋頂下——你受記憶體所限,更快的算術單元或更寬的 SIMD 都沒用;只有更多頻寬或更好的資料重用才有幫助。高強度(每位元組許多運算,像分塊得宜、每個載入值重用許多次的矩陣乘法)達到平屋頂——此時你受運算所限,更快的算術終於划算。Roofline 讓初學者保持誠實:它解釋了為什麼 GPU 龐大的尖峰算術速率在受記憶體所限的核心程式上被浪費,以及為什麼著名的解法是提高算術強度(在快速的晶片上記憶體裡重用資料),而不是買一個更大的算術單元。
把兩個陣列相加,c[i]=a[i]+b[i]:讀 8 位元組(兩個浮點數)、寫 4 個,只做 1 個加法——算術強度約為每 12 位元組 1 個運算,非常低,所以落在斜的記憶體屋頂下、受頻寬所限。分塊的矩陣乘法把每個載入值跨許多乘加重用,達到高強度與平的運算屋頂——只有此時純算術速度才要緊。
屋頂斜的部分是記憶體頻寬限制;平的部分是尖峰運算限制。算術強度決定哪一個封住你。
Roofline 是天花板,不是承諾:真實程式可能因許多原因遠低於兩個限制。它的價值在診斷——它告訴你該追更多頻寬/資料重用(受記憶體限)還是更多算術吞吐量(受運算限),讓你別再最佳化錯的東西。