我打算編寫一個針對.NET平臺的編程語言,這讓我開始考慮定位這種平臺的代碼生成方面。我是寫編譯器的新手,但是我知道在編譯(或者可以)的階段中已經完成了優化。我開始懷疑花費時間優化輸出(在這種情況下CIL,但這也適用於JVM),因爲JIT編譯器和諸如JVM的HotSpot之類的東西可以在運行時進行優化。由於JIT已經優化,因此在針對.NET或JVM時優化生成的代碼(CIL或JVM等價物)會有什麼好處嗎?當代碼生成針對帶JIT的運行時時,是否需要進行優化?
回答
這取決於。有無數的優化。任何給定的編譯器(您的編譯器,JIT編譯器或任何其他編譯器)必須僅實現這些編譯器的一部分。這種選擇取決於可用時間,典型/預期輸入代碼,優先級等,因此構建JIT編譯器的工程師可能選擇了適合他們期望的程序的優化,但對於那些程序來說不太適合關心。
您將必須確定JIT編譯器錯過了哪些優化。當然,這樣做的方式是經驗性的:實際上編寫程序,讓JIT編譯器優化它們(確保正確執行此部分 - 禁用調試,編譯發佈,選擇實際基準等),然後檢查最終的機器碼。尋找意想不到的代碼(當然,您需要大會知識),並確定它是否是錯過的優化,或者JIT是否比您想象的更聰明。
如果是錯過了優化,你有另外一個問題:你不能輸出你想要的機器代碼,你必須產生不同的IL代替。 由於VM不知道的語言特徵(例如JVM上的多種方法),未實現的優化是可能是。您在編譯過程中將其降到了虛擬機的條款中,但您選擇的翻譯並不適合JIT的合格順序,啓發式等。 由於您不能自己輸出機器代碼,您現在必須找到一個替代IL片段對於相同的輸入語言代碼。理想情況下,JIT編譯器處理得很好。發現這可能是想象力的鍛鍊,但這在技術上並不難,只是猜測與基準測試交錯。另一個答案指出,JIT編譯器在時間限制下工作。這可能導致的優化可能發生被錯過(如常量傳播的時間不多了),但隨着JIT編譯器的創造者面臨着同樣的問題,這可能不是太嚴重,如果你不創建太多大/更復雜的代碼。 如果您創建了JIT編譯器無法修復的代碼,那麼您必須在AOT編譯器中複製它的優化。我不認爲這是一個可能的情況,即使發生這種情況,即使非常簡單的優化也應該能夠解決這個問題。
所以,在總結:首先得有個簡單的翻譯,然後尋找錯過的優化,要麼使其更容易優化的JIT編譯器,或者自己做(如果可能的話 - 自適應優化是更難在AOT設置)。
通常,JIT編譯器有一些閾值來控制他們將嘗試執行多少優化。這些可能基於方法的IL的大小和/或已經花費JIT編譯該方法的時間量。所以是的,IL已經被優化可能受益於進一步的JIT優化。與往常一樣,需要權衡:您希望將多少時間添加到您的編譯器(以及測試/維護它們),還是將代碼編譯爲JIT的速度以及優化級別。
改進的程度在很大程度上取決於AOT優化的IL相對於未優化的IL以及控制JIT編譯器的閾值(至少對於Microsoft CLR而言,並不廣爲人知)。找出答案的唯一方法是自己做一些測試。
我覺得這個問題很難回答。
例如,F#編譯器執行tail call optimization,因爲在該語言中使用尾遞歸函數是很常見的,所以F#編譯器在某些情況下可以比JIT編譯器和某些版本的JIT更好地優化它們編譯器根本不執行優化。
因此,您的語言可能有一些常見的操作,其直接執行不會很好。在這種情況下,發出優化的IL代碼是有意義的。
我認爲你應該做的和你在編寫普通程序時一樣:首先用一種簡單易讀的方式編寫代碼。只有當某些事情表現不佳時,纔會嘗試優化。可能值得考慮的是,將來可能需要進行一些優化,並使代碼足夠模塊化,以便由於某種優化而不必重寫一半。但現在,這應該夠了。
編寫一個編譯器已經夠用了(即使你的目標是IL)。先完成並稍後考慮優化。
感謝您的回覆。你在關於特定於語言的優化中提出了一個很好的觀點,這在JIT中是不會做的,這絕對是我沒有想到的。 – Jetti
- 1. 在運行時切換出需要js的優化代碼
- 2. mysql_close()是否需要進行REAL優化?
- 3. 是否應該生成SPIR-V代碼進行優化?
- 4. 是否有可能在運行時生成並運行TemplateHaskell生成的代碼?
- 5. 如何針對Android平臺進行鍼對性優化代碼?
- 6. 機器代碼是否需要運行時環境? MoSync SDK
- 7. 動態生成的java字節碼是否需要優化?
- 8. 在JSON中傳回時是否需要對HTML進行編碼?
- 9. 當對代碼進行更改時,Selenium Java代碼需要從頭開始
- 10. 運行時Orm代碼生成器
- 11. 在運行時生成代碼
- 12. 運行時代碼生成和編譯
- 13. MPMediaItemPropertyIsCloudItem是否需要iOS 6運行時?
- 14. 運行時優化
- 15. 需要幫助進行優化 - 在java中生成幻方塊
- 16. 當DropDownList發生變化時,需要Gridview進行更改
- 17. JIT優化器是否優化乘法?
- 18. 當ExecuteNonQuery完成之前需要進行下一行代碼
- 19. nloptr:在進行優化時,lbfgs()是否需要顯式提供梯度函數?
- 20. 是否可以對CUDA內核進行即時(jit)編譯?
- 21. 針對Grails運行時環境交互式運行代碼
- 22. 編譯器是否會針對布爾分配進行優化?
- 23. Android是否針對不透明視圖進行了優化
- 24. OpenCV 2.0是否針對AMD處理器進行了優化?
- 25. 優化代碼以最小化宏的運行時間
- 26. 是否有可能在運行時生成並執行Rust代碼?
- 27. 當在AS3中進行子類化時,是否需要新的構造函數?
- 28. 針對ASP.net的運行時頁面優化器 - 有何評論?
- 29. 針對用戶生成的Python代碼運行檢查
- 30. 運行「rails生成腳手架」時會運行什麼代碼?
非常感謝您的回答。這很有道理。 – Jetti