![](/img/trans.png)
[英]In x86 assembly, is it better to use two separate registers for imul?
[英]x86 Assembly pushad/popad, How fast it is?
我只是想嘗試在x86程序集中進行非常快速的基於計算的程序,但我需要在調用程序之前推送累加器,計數器和數據寄存器。 手動推動它們的速度更快:
push eax
push ecx
push edx
或者只是使用,
pushad
與彈出一樣。 謝謝
如果你關心性能, pusha
/ popa
幾乎從來popa
。 它們僅在以速度為代價優化代碼大小時才有用,例如在函數周圍保存/恢復寄存器。 但是對於非void
函數來說非常不方便,因為它們會重新加載所有寄存器,因此你必須將返回值存儲在內存中(例如,在將被加載到eax
的堆棧槽中,或者在popad
之后重新加載的其他地方)。
只推送需要保存的寄存器 ,或者想要作為函數args傳遞的寄存器 。 或者, 在內聯匯編中 ,只需讓編譯器通過為任何臨時寄存器聲明"=r"(dummy1)
虛擬輸出操作數來管理寄存器,或者在特定寄存器上使用clobbers。 通常情況下,編譯器可以選擇它可以讓你破壞但不保存的寄存器。 (或者在笨重的MSVC樣式的內聯asm中,編譯器無法為您分配寄存器,因此您必須手動選擇。編譯器解析您的asm以查找clobbers。)
您通常不需要保存/恢復eax
; 對於性能,你可能應該移動mov esi, eax
/ call /使用esi
的值,如果你不能首先計算esi
中的值。 即使用調用保留寄存器來獲取需要在call
存活的值 ,因此重要值的存儲/重新加載不在關鍵路徑上。 相反,存儲/重新加載位於調用者的一個調用保留寄存器的關鍵路徑上,您(或編譯器)在任何循環之外push
/ pop
整個函數。
即使您確實想要推送所有8個整數寄存器(包括esp
!) ,在現代CPU上使用8個單獨的push
指令實際上更快。 pusha / popa是微編碼的, 這可能是前端的問題 。 (雖然8個單字節指令也可能是uop-cache的一個問題。但在實際代碼中,你通常只需要推幾個寄存器,而不是所有寄存器。)
如果您正在優化過時的CPU(如原始的有序Pentium和Pentium II / III),pusha / popa的速度與8 push r
或8 pop r
一樣快,實際上更少的uops,因為它們沒有堆棧引擎消除ESP更新uops。
來自Agner Fog的指令表 :現代CPU具有單uop push reg
和pop reg
,因為這些指令一直被編譯器使用,因此對性能很重要。 推/彈吞吐量通常匹配存儲/負載吞吐量(通常每個時鍾1個存儲或每個時鍾2個負載)。 但popa
器不使用pusha
/ popa
,因此CPU設計人員沒有特別的支持來使它們快速。 如果只運行popa
popa
吞吐量僅限於每個時鍾1個負載。 (我認為在Intel CPU上,測量性能最可能的解釋是popa
不使用堆棧引擎,所以它依賴於esp
。)
英特爾:
pusha
:11 uops,8c吞吐量。 popa
:18 popa
/ 8c吞吐量。 pusha
:16 uops / 8c吞吐量。 popa
:18 popa
/ 9c吞吐量。 pusha
:18 uops / 8c吞吐量。 popa
:10 popa
/ 8c吞吐量。 pusha
:10 uops / 10c吞吐量。 popa
:17 popa
/ 14c吞吐量。 pusha
:4/10 uops / 19c吞吐量。 popa
:4/16 popa
/ 14c吞吐量。 AMD: pusha
/ popa
在一些AMD CPU上出奇的好,尤其是K8。
pusha
:9 uops,8c吞吐量。 popa
:9 popa
, 4c吞吐量 。 (與英特爾不同,AMD的新設計popa
並不比8倍pop
差。) pusha
:9 uops / 8c吞吐量。 popa
:9 popa
/ 8c吞吐量。 (捷豹每個時鍾通常只能負載一次。) pusha
:9 uops / 9c吞吐量。 popa
:14 popa
/ 8c吞吐量。 (Agner將Bulldozer系列的常規pop reg
吞吐量列為每時鍾1個,雖然我認為它們確實有堆棧引擎並且每個時鍾可以執行2次加載。也許堆棧引擎一次只能處理一個堆棧指令?) pusha
:9 uops / 4c吞吐量!! (IDK如何可能,這是表中的錯誤或拼寫錯誤,或者K8合並32位寄存器並執行四個64位存儲)。 popa
:9 popa
/ 4c吞吐量。 這些數字似乎確實是真實的: InstLatx86測量結果與Clawhammer(第一代K8微體系結構)上的pushad
/ popad
4c吞吐量一致。 顯然,AMD在優化pushad
方面付出了一些努力。 您標記了此內聯匯編 。 通常你應該避免在inline-asm中使用call
,所以C編譯器知道這個調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.