简体   繁体   English

为什么在JVM中隐藏JIT编译器没有基础设施?

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

I was reviewing one conference presentation that touched JIT inlining semantics where author pinned down weird behavior (weird only for first look, of course) - C2 was slower than C1 because it couldn't inline method due to excessive inlining depth. 我正在审查一个触及JIT内联语义的会议演示文稿,其中作者固定了奇怪的行为(当然,只有初看起来很奇怪) - C2比C1慢,因为由于内嵌深度过大而无法内联方法。 It may be represented in following example: 它可以在以下示例中表示:

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);
    }
}

As a programmer, i may know there is a field for optimization that compiler doesn't know about. 作为一名程序员,我可能知道有一个编译器不知道的优化领域。 Eg there is plenty of optimization possible if multiplyByTwo would be forcibly inlined, but due to various constraints (eg method size or inlining depth) it may be omitted from inlining. 例如,如果multiplyByTwo将被强制内联,则可以进行大量优化,但是由于各种约束(例如方法大小或内联深度),它可以从内联中省略。 Why there is no way to tell the compiler "hey, i'm pretty sure you should prefer inlining that method rather not"? 为什么没有办法告诉编译器“嘿,我很确定你应该更喜欢内联那个方法而不是”? I'm sure i'm not the first one to think about this and there was discussion that resulted in not implementing such feature - why? 我敢肯定,我不是第一个考虑这个问题的人,并且讨论导致没有实现这样的功能 - 为什么?

ps please note that i'm talking about hints rather than directives; ps请注意我正在谈论提示而不是指令; i do understand that latter choice would result in more harm than benefit. 我明白后一种选择会带来更多的伤害而不是利益。

In fact, there is an infrastructure to control HotSpot JVM compiler. 实际上, 一个控制HotSpot JVM编译器的基础设施。

1. Compiler command file 1.编译器命令文件

You may specify a file containing compiler commands with -XX:CompileCommandFile= JVM option. 您可以使用-XX:CompileCommandFile= JVM选项指定包含编译器命令的文件。 There are commands to force inlining, to exclude a method from compilation, to set a per-method option (eg MaxNodeLimit ) and so on. 有一些命令强制内联,从编译中排除方法,设置每个方法选项(例如MaxNodeLimit )等等。 The full list of available commands can be found here . 可以在此处找到可用命令的完整列表。

An example Compiler command file may look like 编译器命令文件的示例可能如下所示

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

2. Annotations 2.注释

JDK-specific annotations are another way to control JVM optimizations. JDK特定的注释是控制JVM优化的另一种方法。 There are certain annotations that HotSpot JVM knows about, eg HotSpot JVM知道某些注释,例如

Note: All these mechanisms are non-standard. 注意:所有这些机制都是非标准的。 They apply only to OpenJDK and Oracle JDK. 它们仅适用于OpenJDK和Oracle JDK。 There is no standard way to hint JVM compiler, because there are many JVM implementations with completely different compilation strategies. 没有标准的方法来提示JVM编译器,因为有许多JVM实现具有完全不同的编译策略。 Particularly, there are JVMs with no JIT compilation at all. 特别是,有些JVM根本没有JIT编译。

Well, the are hints to the JVM's optimizer that this method is a good candidate for inlining: 好吧,这 JVM优化器的提示,这个方法是内联的一个很好的候选者:

  • It's static or private , ie non-overridable 它是staticprivate ,即不可覆盖的
  • It's extremely short 它非常短
  • It's called several times within a loop 它在循环中被多次调用

In fact, your assumption that this method is a good candidate is based on the same technical evidence, so adding a hint that you think that this is a good inlining candidate would not add any new information, only redundancy. 实际上,您假设此方法是一个很好的候选者是基于相同的技术证据,因此添加一个暗示, 认为这是一个好的内联候选者不会添加任何新信息,只会添加冗余。

So if the JVM still doesn't inline the method, for whatever reason, despite all these technical properties speaking for inlining, there is no reason to assume that a non-mandatory, non-technical hint, most likely stemming from the same technical properties will turn the JVM's decision. 因此,如果JVM仍然没有内联该方法,无论出于何种原因,尽管所有这些技术属性都在内联,但没有理由假设非强制性,非技术性提示,很可能源于相同的技术属性将改变JVM的决定。

You can pick any potential reason you want, protection against certain problems, too restrictive limits, even a flawed JVM implementation, in either case, you'll see that the same reason applies to a method having your hint as well, even if it turns out to be an unfounded reason, as that also applies to a method without your hint. 你可以选择你想要的任何潜在理由,防止某些问题,限制性太强,甚至是有缺陷的JVM实现,在任何一种情况下,你都会看到同样的原因也适用于具有你提示的方法,即使它已经转向这是一个没有根据的理由,因为这也适用于没有提示的方法。 So in the latter case, the obvious solution would be to fix the flaws within the JVM, rather than adding a general hint mechanism. 因此在后一种情况下,显而易见的解决方案是修复JVM中的缺陷,而不是添加一般提示机制。

A general hinting mechanism is especially questionable, as the code is supposed to be platform independent. 一般的提示机制尤其值得怀疑,因为代码应该是平台无关的。 If you look at a particular run in a known environment with a particular JVM implementation, things look different. 如果您在具有特定JVM实现的已知环境中查看特定运行,则情况会有所不同。 Eg HotSpot supports the -XX:CompileCommand option. 例如,HotSpot支持-XX:CompileCommand选项。 So in your case, you could use -XX:CompileCommand=inline,your/class/Name,multiplyByTwo to try to convince the JVM to inline the method. 所以在你的情况下,你可以使用-XX:CompileCommand=inline,your/class/Name,multiplyByTwo来试图说服JVM内联方法。 Of course, the correct spelling is important. 当然,正确的拼写很重要。 In your question, the method is once named multipleByTwo , then multiplyByTwo 在你的问题中,该方法曾被命名为multipleByTwo ,然后multiplyByTwo ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM