天天看點

cpu out of order, 性能優化

這是以前研究所學生的時候寫的一篇文章

今天看了一篇文章關于cpu亂序執行的講解,主題思想是cpu能并行的處理指令,這裡的并行不是多核并行的處理,而是在某種情況下,上下2條指令可以被一個核一起送行,還有可能在下面的指令先運作,稱為亂序執行,out of order,這也帶來了超标量,1個時鐘周期可以運作大于1條指令。這在以前是不可想象的,在理想情況下,一個時鐘最多執行1條,但是創新是無界限的。

一個簡單的實驗

cpu out of order, 性能優化

過程為對eax執行3次加法,循環差不多4g次,差一點點,無關緊要,産生執行檔案反彙編如下

cpu out of order, 性能優化

循環内部一共五條指令,4g次循環,就是20g個指令需要執行,使用time 計算運作時間10次測試值為

7.12 7.23 7.24 7.07 7.14 7.17 7.21 7.30 7.16 6.99這裡是user時間,使用者态時間,忽略其他函數包括main之前的函數執行時間

就是在這20g次得指令執行上花了大約7s時間,本機的配置為酷睿的2.1ghz,7s的時間最多也隻能有14g的周期,按照一般理論,執行不了20g次指令,這還是在每個指令都是單周期的理想情況下

這就是亂序執行帶來的超标量性能。

對于此現象的稍微詳細一點的解釋可以是這樣,

5條指令,每一條都是對cpu狀态機的一個改變,對于上下沒有依賴的指令可以一起執行

比如

cpu out of order, 性能優化

這2條可以并行運作,但是

cpu out of order, 性能優化

這2條就不可以并行運作,對于這5條指令可以了解為這樣的一個過程

cpu out of order, 性能優化

每一行代表一個機器周期,對eax的三次相加,必須等到前一次運算完成以後才能進行下一次的相加,但是對于edx的減法就可以和第一次eax的加法一起運作,其實edx就是c代碼的那個i,這裡就是亂序的展現,因為edx的減法在後面,但是先于2個eax的加法運作,沒有按照固定順序。但是不管怎麼亂序,指令執行完以後的結果需要和順序的一樣。jne 80483a8這個指令要等到對edx減法完成是才能運作,因為要根據減法運算的結果的判斷。

是以這5條指令 4g次循環其實是3個周期 4g次循環為12g個周期,7s的時間2ghz 處理器可以有14g個周期。是以加上main之前的庫代碼為2g個周期,就差不多7s 的運作時間。

以下是對代碼的另一種實驗。對eax的3次加法改成分别對eax ebx ecx的3次加法,這個看上去是差不多,都是對寄存器加法運算,但是對于現代的處理器有很大的差别。

c代碼改為

cpu out of order, 性能優化

對于的a.out執行檔案反彙編為

cpu out of order, 性能優化

循環還是5條指令和原來的一樣,隻是原來是eax3次加法變成現在的eax ebx ecx的三次加法,測試的運作時間為

4.31 4.48 4.28 4.33 4.28 4.25 4.19 4.34 4.34 4.33

這是絕對的減少,這就很奇怪,隻是對寄存器不一樣,按照上面的方法可以畫一下cpu運算資料流向圖

cpu out of order, 性能優化

因為對eax ebx ecx 3條指令沒有上下依賴關系,目前intel處理器每個核有三個獨立的加法器(可以測試具體有幾個加法器),是以其實這3條指令是一起運作的,估計cpu資料流,一次循環其實隻需要2個周期就可以了,4g次循環隻需要8g個周期,對于一個2ghz的處理器來說時間也剛好是4s差不多,和測試結果完全比對。這就是cpu的亂序執行的能力。對于性能優化,在c的展現中,在循環中,在連續的幾次運算中資料沒有依賴性是重點。把運算過程的中間結果都放在同一個變量中會比較慢。

就算再增加一個加法運算把原來的3次改為4次,

cpu out of order, 性能優化

運算時間還是和上一次是一樣的。

因為cpu資料流圖

cpu out of order, 性能優化

在一個循環的運作周期上還是一樣的,4.22 4.44 4.31 4.30 4.23 4.21 4.22 4.24 4.22 4.23

如果增加到5個的話,資料流回變成

cpu out of order, 性能優化

在2個時鐘周期中三個加法器會滿負載運作,這樣就會影響到jne 80483a8的運算,

cpu out of order, 性能優化

其實這條指令也是需要加法器支援的,從上面可以看到這條指令的機器碼是 75 f2效果是向前跳12個偏移,這是一個相對偏移跳轉指令,運算過程為下一條指令位址0xbc+2=0xbe 加上0xf2

加上f2就是減14 等于0xb0,是以需要加法器計算最終的位址。但是加法器在前面已經滿負荷運作,是以勢必會增加每個循環的周期數。測試結果為

5.17 5.52 5.05 5.31 5.09 5.15 5.30 5.31 5.39 5.04

明顯的比前面的運算時間要增加。

繼續閱讀