簡體   English   中英

為什么在JVM中隱藏JIT編譯器沒有基礎設施?

[英]Why there is no infrastrucutre for hinting JIT compiler in JVM?

我正在審查一個觸及JIT內聯語義的會議演示文稿,其中作者固定了奇怪的行為(當然,只有初看起來很奇怪) - C2比C1慢,因為由於內嵌深度過大而無法內聯方法。 它可以在以下示例中表示:

public static int multipleByTwo(int x) {
    return x * 2;
}

public static void entrypoint() {
    int sum = 0;
    for (int i = 0; i < 10_000_000; i++) {
        // due to some arbitrary cause, multiplyByTwo doesn't get inlined
        sum += multiplyByTwo(i);
    }
}

作為一名程序員,我可能知道有一個編譯器不知道的優化領域。 例如,如果multiplyByTwo將被強制內聯,則可以進行大量優化,但是由於各種約束(例如方法大小或內聯深度),它可以從內聯中省略。 為什么沒有辦法告訴編譯器“嘿,我很確定你應該更喜歡內聯那個方法而不是”? 我敢肯定,我不是第一個考慮這個問題的人,並且討論導致沒有實現這樣的功能 - 為什么?

ps請注意我正在談論提示而不是指令; 我明白后一種選擇會帶來更多的傷害而不是利益。

實際上, 一個控制HotSpot JVM編譯器的基礎設施。

1.編譯器命令文件

您可以使用-XX:CompileCommandFile= JVM選項指定包含編譯器命令的文件。 有一些命令強制內聯,從編譯中排除方法,設置每個方法選項(例如MaxNodeLimit )等等。 可以在此處找到可用命令的完整列表。

編譯器命令文件的示例可能如下所示

inline java.util.ArrayList::add
exclude *::<clinit>
print com.example.MyClass::*

2.注釋

JDK特定的注釋是控制JVM優化的另一種方法。 HotSpot JVM知道某些注釋,例如

注意:所有這些機制都是非標准的。 它們僅適用於OpenJDK和Oracle JDK。 沒有標准的方法來提示JVM編譯器,因為有許多JVM實現具有完全不同的編譯策略。 特別是,有些JVM根本沒有JIT編譯。

好吧,這 JVM優化器的提示,這個方法是內聯的一個很好的候選者:

  • 它是staticprivate ,即不可覆蓋的
  • 它非常短
  • 它在循環中被多次調用

實際上,您假設此方法是一個很好的候選者是基於相同的技術證據,因此添加一個暗示, 認為這是一個好的內聯候選者不會添加任何新信息,只會添加冗余。

因此,如果JVM仍然沒有內聯該方法,無論出於何種原因,盡管所有這些技術屬性都在內聯,但沒有理由假設非強制性,非技術性提示,很可能源於相同的技術屬性將改變JVM的決定。

你可以選擇你想要的任何潛在理由,防止某些問題,限制性太強,甚至是有缺陷的JVM實現,在任何一種情況下,你都會看到同樣的原因也適用於具有你提示的方法,即使它已經轉向這是一個沒有根據的理由,因為這也適用於沒有提示的方法。 因此在后一種情況下,顯而易見的解決方案是修復JVM中的缺陷,而不是添加一般提示機制。

一般的提示機制尤其值得懷疑,因為代碼應該是平台無關的。 如果您在具有特定JVM實現的已知環境中查看特定運行,則情況會有所不同。 例如,HotSpot支持-XX:CompileCommand選項。 所以在你的情況下,你可以使用-XX:CompileCommand=inline,your/class/Name,multiplyByTwo來試圖說服JVM內聯方法。 當然,正確的拼寫很重要。 在你的問題中,該方法曾被命名為multipleByTwo ,然后multiplyByTwo ...

暫無
暫無

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

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