我正在研究一些關於程序集和我正在閱讀的材料,作者說在x86操作系統上編譯爲16位的程序旋轉速度更慢,對於x64也是如此,對於x64,32位編譯程序運行速度較慢...爲什麼在x86操作系統上運行16位程序會變慢?
這是爲什麼發生? 在計算機內存和處理器中會發生什麼情況,以便程序的16位或32位機器分別以32位和64位的速度緩慢旋轉?
我正在研究一些關於程序集和我正在閱讀的材料,作者說在x86操作系統上編譯爲16位的程序旋轉速度更慢,對於x64也是如此,對於x64,32位編譯程序運行速度較慢...爲什麼在x86操作系統上運行16位程序會變慢?
這是爲什麼發生? 在計算機內存和處理器中會發生什麼情況,以便程序的16位或32位機器分別以32位和64位的速度緩慢旋轉?
關於16在32位系統上運行較慢位程序,我可以告訴你這一點。 當Intel從16位變爲32位時,他們不得不擴展指令集來處理新的32位寄存器,但保持與16位程序的二進制兼容性。
爲了實現這個目標,如果我記得很清楚,他們添加了一個前綴66h,當應用於任何使用16位寄存器的指令時,使該指令使用32位寄存器。
例如,一個16位指令,如MOV AX,BX,以66H前綴,變成MOV EAX,EBX
但是,這則規定的罰款對新的32個指令,因爲它們需要在至少需要一個額外的內存讀取週期才能執行。然後英特爾創建了所謂的32位段和16位段。
基本上,任何一段代碼都必須駐留在代碼段中。在80386之前,所有段都使用16位指令,所有指令都假定使用16位寄存器。
Intel的32段也包含代碼,但是這次每條指令都假定使用32位寄存器,所以在32位段中,MOV EAX,EBX的操作碼與MOV AX的操作碼相同,BX在16位段。
這允許程序不必爲每個32位指令使用66h前綴。沒有懲罰了。
但是...如果我必須在一個32位段的程序中使用16位寄存器,該怎麼辦?這些使用16位寄存器的指令必須使用前綴66h。
因此:使用16位寄存器的指令在16位段中前綴不固定,並且在32位半角前綴。使用32位寄存器的指令在32位段中前綴固定,並在16位段中前綴。另外:從奔騰處理器開始,我們有兩條並行執行指令的管道。對於要使用的這些管道,進入它們的指令必須屬於Intel命名爲「RISC核心」的內容:指令的子集不再作爲CPU內部的微程序執行,而是使用有線邏輯。你猜怎麼了?前綴指令和使用16位寄存器在16位段中執行的代碼不屬於該組,因此不能與另一個並行執行。當前綴指令設法輸入其中一條管道時,另一條流水線被阻塞,從而影響CPU的性能。
我不知道你所說的旋轉的意思,但一般來說有可能是這裏的幾個因素(裝配作業?) -
CPU企業沒有真正去支持的努力舊的遺留模式和ISA子集。 x87就是一個很好的例子,任何並不真正需要這種精確度的水平都會使用SSE/AVX進行性能關鍵任務,而不僅僅是因爲矢量化。
每當x86 CPU公司增加它們的寄存器大小時,它們都保留舊的寄存器組,併爲較長的版本添加邏輯名稱。對兼容性的需求要求舊操作仍然可以在同一個寄存器上工作,因此現在可以在同一個程序中寫入ah/al,ax,eax和rax。在這些情況中的一些情況下(即8位/ 16位部分),這種兼容性要求您的CPU在寫入較低部分時保持寄存器的上半部分完好無損,這樣做會隱式引入合併操作,這可能會導致減速。更糟糕的是,您可能會引入錯誤的依賴關係,因爲每次寫入16位寄存器都會要求您在上一部分操作的上半部分進行合併。
也在這裏看到的 - Why do most x64 instructions zero the upper part of a 32 bit register
關於「程序旋轉速度更慢」...呃...程序不「旋轉」,而是「執行」。如果你正在談論位旋轉指令......那麼。恰巧8086有兩個版本的位循環指令:一個使用指定要旋轉的位數的inmediate參數,另一個使用寄存器(通常是CX/ECX)來指定它。
問題是8086處理器不允許任何其他值爲1的inmediate參數(但CX/ECX中的值可能大於1)。 80386及更高版本的處理器允許使用任何其他值作爲中間操作數。此外,32位處理器僅使用指定旋轉量的操作數的低5位,所以操作不超過31(將32位reigster旋轉超過31次毫無意義)。 8086處理器不會強加此限制,因此需要花費更多時間進行操作。
我真的不知道這是不是你的書的意思是「旋轉得更慢」。我記得旋轉操作只能在其中一個管道中執行,而不能同時在兩個管道中執行,因此兩個連續的旋轉指令不能配對。
簡短回答:因爲CPU爲最近構建的代碼的優點進行了優化,代價是舊代碼,舊代碼。 –