簡體   English   中英

JVM JIT 編譯器優化的限制

[英]Limits of JVM JIT-Compiler Optimizations

我目前正在研究從自定義 DSL 到 Java 的編譯器,同時在此過程中執行一些基本的性能優化。 我最大的問題是,沒有找到關於 JIT 編譯器將在優化(通過)方面做什么或在什么范圍內進行(例如,復雜的死代碼消除,參見下面的示例)的學術資源。 有很多博客文章說由於某些時間限制,JIT 編譯器不會做 AOT 編譯器會做的所有優化,但沒有提到這實際上意味着什么。 是否有一般的經驗法則? 我是否需要深入研究 OpenJDK C++ 源代碼才能理解這一點? 有沒有這方面的研究? 如果沒有,是否有關於 JVM JIT 進行哪些優化的最可靠資源? 我發現的最新資源是關於 Java 5 的,它已經過時了 ( http://www.oracle.com/technetwork/java/5-136747.html )

這是一個簡單的例子,復雜的死代碼消除”場景我發現JVM JIT無法消除,因為變量cells_S_S_S沒有在任何地方使用(記住這是自動生成的代碼):

List<List<List<Cell>>> cells_S_S_S = new ArrayList<>(pla_S.size());
...
for (int pla_S_itr_45 = 0; pla_S_itr_45 < pla_S_size_45; ++pla_S_itr_45) {
        ...
        List<List<Cell>> cells_S_S = new ArrayList<>(tmpVarIf20_S.size());
        for (int tmpVarIf20_S_itr_44 = 0; tmpVarIf20_S_itr_44 < tmpVarIf20_S_size_44; ++tmpVarIf20_S_itr_44) {
            ...
            List<Cell> cells_S = _state.getCells();
            ...
            cells_S_S.add(cells_S);
        }
        ...
        cells_S_S_S.add(cells_S_S);
    }

這種“嵌套死代碼”並沒有被消除,這讓我自己執行了所說的優化。

簡而言之:我想知道 JVM JIT 的功能,以便我可以將自己的優化過程集中在正確的領域。

我想知道 JVM JIT 的功能,以便我可以將自己的優化過程集中在正確的領域。

簡單的回答:不要。

你必須考慮兩件事:

  1. 是的,Oracle HotSpot JVM JIT 引擎在多次通過期間執行廣泛的優化。 您列出的一些(死代碼消除、內聯、去虛擬化等)等等。
    需要注意的是,JIT 引擎的行為不是標准化的,其他公司的 JVM 的行為方式也不同。 我從未見過全面描述 HotSpot 如何在內部做出決策或支持的優化列表的文檔,我非常懷疑此類文檔是否存在(不是來自 Oracle,也不是來自社區)。 您可以深入了解 HotSpot VM 的來源,但是:
  2. HotSpot 不斷嘗試確定應用程序中的熱點,並以不確定的方式決定需要 jitted 的內容、在當前上下文中如何執行(對於較熱的方法,應用代價高昂的優化是有意義的)以及哪些 jitted 方法需要被丟棄並可能重新編譯。
    您的應用程序的狀態不穩定,JIT 引擎不斷決定如何處理它,並根據當前環境選擇將應用哪組優化。

您正在嘗試針對特定的 JIT 行為優化從 DSL 轉譯的代碼,但是您所做的每個假設可能對一次特定的運行有效,但對另一次無效。 或者一段時間后不再有效,當 jit 引擎決定放棄你的方法的 jitted 版本以釋放內存或以不同的結果再次編譯它時。

JIT 和 AOT 之間的唯一區別是后者沒有時間限制,因此您可以嘗試生成最好的代碼,以達到某種程度的質量。

JIT 優化實際上比Whole-Program 優化強大得多。 JIT 優化臨時調整代碼以獲得最佳性能,並基於對代碼的假設進行極其不安全的優化。 例如,JIT 優化器可以預先計算某些內容,然后在假設出錯時將其回滾。 JIT 內聯器通過內聯方法幫助 JIT 優化器,以便它們可以適應特定的調用者。

暫無
暫無

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

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