簡體   English   中英

編譯器優化:在哪里/如何才能了解不同優化的收益?

[英]Compiler optimizations: Where/how can I get a feel for what the payoff is for different optimizations?

在我對各種編譯器書籍和網站的獨立研究中,我正在學習編譯器可以優化編譯代碼的許多不同方法,但我無法確定每個優化將給予多少好處。

大多數編譯器編寫者如何決定首先實現哪些優化? 或者哪些優化值得努力或不值得努力? 我意識到這將在代碼類型甚至單個程序之間有所不同,但我希望大多數程序之間有足夠的相似性來說,例如,一種給定的技術通常會比另一種技術提供更好的性能增益。

我發現在實現教科書編譯器優化時,他們中的一些傾向於反轉其他優化所做的改進。 這需要大量的工作來試圖找到它們之間的正確平衡。

所以你的問題確實沒有一個好的答案。 一切都是權衡。 許多優化在一種類型的代碼上運行良好,但對其他類型則是悲觀的。 這就像設計一個房子 - 如果你把廚房做得更大,那么食品室就會變小。

構建優化器的真正工作是嘗試各種組合,對結果進行基准測試,並像主廚一樣,選擇合適的成分組合。

舌頭在臉頰:

  1. 傲慢
  2. 基准
  3. 困窘

更嚴重的是,它取決於您的編譯器的體系結構和目標。 這是一個人的經歷......

尋求“巨額回報”:

  • 本機代碼生成
  • 注冊分配
  • 指令調度

去尋找剩余的“低懸的水果”:

  • 力量減少
  • 不斷傳播
  • 復制傳播

保持標記。

看看輸出; 修復任何看起來很愚蠢的東西。

通常情況下,組合優化甚至重復優化過程比您預期的更有效。 好處不僅僅是各部分的總和。

您可能會發現引入一個優化可能需要另一個優化。 例如,具有Briggs-Chaitin寄存器分配的SSA確實受益於復制傳播。

從歷史上看,存在“算法”優化,在大多數情況下代碼應該從中受益,例如循環展開 (編譯器編寫者應首先實現那些“記錄”和“測試”優化)。

然后有一些優化類型可以從所使用的處理器類型中受益(例如在現代CPU上使用SIMD指令)。

有關參考,請參閱Wikipedia上的編譯器優化

最后,可以測試各種類型的優化來分析代碼或執行重復執行的准確時間。

我不是編譯器編寫者,但為什么不只是逐步優化代碼的部分,一直在進行分析?

我的優化方案通常是:

1)確保程序正常運行

2)找到要優化的東西

3)優化它

4)將測試結果與1中的測試結果進行比較; 如果它們不同,那么優化實際上是一個突破性的變化。

5)比較時序差異

漸漸地,我會更快。

我使用分析器選擇要關注的部分。 我不確定通過詢問編譯器編寫者你會得到多少額外信息。

這實際上取決於你正在編譯的內容。 最近在LLVM郵件列表上對此進行了相當好的討論 ,它當然對於他們可用的優化器有些具體。 他們使用縮寫進行了很多優化過程,如果你不熟悉他們正在折騰的任何首字母縮略詞,你可以查看他們的傳遞頁面以獲取文檔。 最終,您可以花費數年時間閱讀有關此主題的學術論文。

這是學術論文(ACM可能?)可能是最新信息的更好來源之一的主題之一。 如果你真的想知道,最好的辦法可能是以未經優化的形式創建一些代碼,一些是優化所采用的形式(循環展開等),並實際找出增益可能使用編譯器的位置優化已關閉。

值得注意的是,在許多情況下,編譯器編寫者不會花太多時間(如果有的話)確保他們的庫得到優化。 基准測試往往不再強調甚至忽略庫差異,大概是因為你可以使用不同的庫。 例如,GCC中的置換算法漸近*效率低於嘗試置換復雜數據時的效率。 這與在調用交換函數期間錯誤地制作深拷貝有關。 這可能會在大多數編譯器中通過引入rvalue引用(C ++ 0x標准的一部分)得到糾正。 將STL重寫得更快非常容易。

*這假設被置換的類的大小是可變的。 例如,如果int的向量更大,則置換int的向量向量將減慢。

可以提供大加速但很少完成的是插入內存預取指令。 訣竅在於提前了解程序想要的內存,從不要求錯誤的內存,也不要丟失D-cache。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM