Stack Pointer Tracker
在Intel 64與IA-32架構中,存在一類用于跳轉到以及跳出程序段的指令:PUSH、POP、CALL、LEAVE與RET。這些指令可以在沒有其余指令的干預下隱式地更新棧寄存器(ESP),維護棧內的參數,然后再執行其它相應的操作。在P3處理器之前,這類指令都會被解碼成多條μops。
從PM處理器開始,引入了Stack Pointer Tracker技術。PM處理器的decoder中添加了對上述指令的處理邏輯,使得上述指令中的隱式更新ESP部分可以在decoder內完成。這種技術帶來了以下便利:
- 節約解碼帶寬,因為少輸出了一個更新ESP的μop,PUSH、POP、以及RET都變成了單μop指令。
- 節約執行帶寬,因為更新ESP的運算不用在EU內執行了。
- 提升了out-of-order處理的并行度,因為ESP間的隱式依賴已經被消除。
- 降低了功耗,因為ESP的更新采用了更小型的硬件。
?
不過ESP除了上述指令中的隱式運算外,還能進行顯式運算。ESP的隱式運算是在decoder中以in-order順序進行的,而顯式運算是在execution unit中以out-of-order順序進行的,為了使得ESP相關指令正確執行,有必要對decoder以及EU中的ESP進行同步。同步分為兩部分:
- decoder執行完ESP相關運算后,把ESP更新到EU。
- EU執行完ESP相關運算后,把ESP更新到decoder。
這需要EU以及decoder有對ESP的跟蹤能力(Stack Pointer Tracking),不過由于指令在經過renamer的時候有用RAT記錄了所有寄存器的映射,因此不單單EU,decoder也能跟蹤到ESP的變化。
?
sync ESP from decoder to EU
decoder向EU更新ESP的實現方法是把ESP分為兩部分
ESPP = ESPO + ESPD
其中ESPP是程序員眼中的ESP值(ESP實際值);ESPO是EU中用到的ESP,顯式的ESP運算會用到該數值;ESPD是decoder中維護的差值,隱式ESP運算會修改這個數值。以下面的例子來闡述其中機制(僅供參考)
如上圖所示,在解碼POP/PUSH等隱式修改ESP的指令的時候,可以得到這些指令對ESP修改的差值ESPD,然后通過這些差值,decoder內部的硬件邏輯可以直接算出ESPP并用于這類指令的后續操作。一旦碰上顯式訪問ESP的指令,如果此時ESPD不為0,則插入一條用于更新ESPO的μop,然后把ESPD置為0。
?
sync ESP from EU to decoder
由于在pipeline中decoder位于EU的前方,所以有可能會出現這種情況:decoder在計算ESPP時,所需的ESPO還沒處理完成,此時ESPP只能依靠推測來得到,即speculative calculation。由于可能會推測錯誤,因此在得到ESPO后還需要進行判斷,如果出錯則應該把指令回溯,重新以正確的ESP再次執行。有興趣的可以查看Reference中的第二三條鏈接作為拓展閱讀。
?
?
優化建議
StackPointerTracker會在隱式修改ESP指令之后的第一條顯式訪問ESP的指令插入一條同步指令,因此如果對ESP的隱式修改與顯式訪問指令頻繁交替,則會不斷添加同步μop,因而會影響指令的處理效率。不過無論是隱式修改ESP還是顯式訪問ESP都是函數不可或缺的一部分,因此在函數體內盡量減少對ESP的隱式顯式交替訪問(盡量不用PUSH/POP指令),某些critical代碼善用inline。
?
Reference:
Intel? 64 and IA-32 Architectures Optimization Reference Manual
Literature: S. Gochman, et al.: The Intel Pentium M Processor: Microarchitecture and Performance. Intel Technology Journal, vol. 7, no. 2, 2003
M. Bekerman, et al. : Early Load Address Resolution Via Register Tracking
轉載于:https://www.cnblogs.com/TaigaCon/p/7711504.html
總結
以上是生活随笔為你收集整理的Stack Pointer Tracker的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: clumsy模拟客户端网络差的场景的使用
- 下一篇: tomcat 下catalina.out