Microsoft編譯器似乎生成x64代碼,其中包含與16個字節對齊的函數(而不是數據),即除了目標文件中的最後一個函數以外,每個函數都使用0xCC填充其代碼(中斷指令,大概是爲了更容易的調試)直到下一個16字節邊界。函數代碼對齊到16個字節
這是爲什麼?它實際上是否提高了性能?如果是這樣,怎麼樣?直覺上,我會預料如果有什麼它應該略微降低性能緩存的原因。
Microsoft編譯器似乎生成x64代碼,其中包含與16個字節對齊的函數(而不是數據),即除了目標文件中的最後一個函數以外,每個函數都使用0xCC填充其代碼(中斷指令,大概是爲了更容易的調試)直到下一個16字節邊界。函數代碼對齊到16個字節
這是爲什麼?它實際上是否提高了性能?如果是這樣,怎麼樣?直覺上,我會預料如果有什麼它應該略微降低性能緩存的原因。
在大多數x86-64架構上,要執行的代碼是通過16字節對齊的行從內存中獲取的(see 「Instruction fetch」 sections)。這意味着如果目標是16字節的倍數,傳入分支將從最大數量的預取和解碼指令開始。當執行不會從前面的代碼轉換(通過)到標籤,就像函數的開始時一樣,填充指令並不重要,似乎對齊標籤通常是一種收益。優化器通常會這樣做,除非他們被告知需要優化代碼大小(但由於您在問題中陳述的原因,它可能仍然是一個損失:它會降低代碼密度並使各種緩存效率降低)。
該案例也可以用於對齊分支目的地,可以通過fall-though(通常是循環的開始)到達。在這種情況下,折衷更不可能是有利的,因爲一些nop指令需要在掉頭期間執行,如果目的地沒有對齊,那麼這些指令就不會出現在那裏。有一些技巧可以創建比多個短nop指令更快解碼的長nop指令,但這仍然無助於平均,優化編譯器只有在明確指示(例如GCC的-falign-loops
選項,而不是-falign-functions
)時纔會執行此操作。向下滾動到關於this page的-falign-*
選項的討論)。
操作碼(機器操作),32位或64位的大小是多少? –