即时编译和堆栈替换之间的差异

发布于 2025-01-01 17:43:23 字数 126 浏览 2 评论 0原文

他们俩几乎都做同样的事情。确定该方法是热门方法并对其进行编译而不是解释。使用 OSR,您只需在编译后立即转移到编译版本,这与 JIT 不同,在 JIT 中,第二次调用方法时会调用已编译的代码。

除此之外,还有其他的区别吗?

Both of them pretty much do the same thing. Identify that the method is hot and compile it instead of interpreting. With OSR, you just move to the compiled version right after it gets compiled, unlike with JIT, where the compiled code gets called when the method is called for the second time.

Other than this, are there any other differences?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一般来说,即时编译是指在运行时编译本机代码并执行它,而不是(或除了)解释之外。有些虚拟机,例如 Google V8,甚至没有解释器;他们 JIT 编译每个执行的函数(具有不同程度的优化)。

堆栈替换 (OSR) 是一种在同一函数的不同实现之间进行切换的技术。例如,您可以使用 OSR 在完成编译后立即从解释或未优化的代码切换到 JIT 代码。

当您将某个函数在运行时识别为“热”函数时,OSR 非常有用。这可能不一定是因为该函数被频繁调用;它可能只被调用一次,但它会在一个大循环中花费大量时间,这可以从优化中受益。当 OSR 发生时,VM 暂停,目标函数的堆栈帧被替换为等效帧,该帧可能在不同位置具有变量。

OSR 也可以发生在另一个方向:从优化代码到未优化代码或解释代码。优化的代码可能会根据过去的行为对程序的运行时行为做出一些假设。例如,如果您只见过一种类型的接收者对象,则可以将虚拟或动态方法调用转换为静态调用。如果后来发现这些假设是错误的,则可以使用 OSR 回退到更保守的实现:优化的堆栈帧转换为未优化的堆栈帧。如果虚拟机支持内联,您甚至可能最终将优化的堆栈帧转换为几个未优化的堆栈帧。

In general, Just-in-time compilation refers to compiling native code at runtime and executing it instead of (or in addition to) interpreting. Some VMs, such as Google V8, don't even have an interpreter; they JIT compile every function that gets executed (with varying degrees of optimization).

On Stack Replacement (OSR) is a technique for switching between different implementations of the same function. For example, you could use OSR to switch from interpreted or unoptimized code to JITed code as soon as it finishes compiling.

OSR is useful in situations where you identify a function as "hot" while it is running. This might not necessarily be because the function gets called frequently; it might be called only once, but it spends a lot of time in a big loop which could benefit from optimization. When OSR occurs, the VM is paused, and the stack frame for the target function is replaced by an equivalent frame which may have variables in different locations.

OSR can also occur in the other direction: from optimized code to unoptimized code or interpreted code. Optimized code may make some assumptions about the runtime behavior of the program based on past behavior. For instance, you could convert a virtual or dynamic method call into a static call if you've only ever seen one type of receiver object. If it turns out later that these assumptions were wrong, OSR can be used to fall back to a more conservative implementation: the optimized stack frame gets converted into an unoptimized stack frame. If the VM supports inlining, you might even end up converting an optimized stack frame into several unoptimized stack frames.

故人的歌 2025-01-08 17:43:23

是的,差不多就是这样。 即时编译可以通过编译“热点”(spots)来提高性能已知/应该经常执行的字节码)字节码到本机指令。 堆栈上替换通过替换长时间运行的解释型“来补充 JIT 功能”当它可用时,它的编译版本会被称为“hot”字节码。提到的 -Stack Replacement 文章展示了一个很好的例子,如果没有 OSR,JIT 编译就不会很有用。

Yes, that's pretty much it. Just-in-time compilation can improve performance by compiling "hot spots" (spots of bytecode that are known / supposed to execute very often) of bytecode to native instructions. On-Stack Replacement complements JIT capabilities by replacing long running interpreted "hot" bytecode by it's compiled version when it becomes available. The mentioned On-Stack Replacement article shows a nice example where JIT compilation would not be very useful without OSR.

羁绊已千年 2025-01-08 17:43:23

JIT 只是.. 查找方法调用的数量,如果超过阈值,(-XX:CompileThreshold=)它会编译(到机器代码/本机)并缓存该方法。下次调用时,将调用编译版本。
OSR 很有趣。假设一个巨大的 for 循环在解释模式下运行。当超过编译阈值时,JVM 决定在某个时间点进行编译。因此,当循环仍在运行时,其解释版本可以在代码仍在运行时替换为编译为本机版本!
所以本质上它就是它所说的。将运行时仍在堆栈上运行的解释代码替换为编译代码。
这也可能导致一个有趣但良性的问题,称为“谁吃了我的变量”。请参阅谁吃了我的变量

JIT is just.. looks for number of method invocations, and if it crosses a threshold, (-XX:CompileThreshold=) it compiles (to machine code/ native) and caches the method. On next invocation, the compiled version will invoke.
OSR is interesting. Supposing a gigantic for loop is running in interpret mode. JVM decides to compile at some point of time when it has crossed the compile threshold. So while the loop is still running, its interpreted version can get replaced with a compiled to native version while the code is still running!
So essentially it is exactly what it says. Replacing interpreted code, which is still running on stack, while it is running, with compiled code.
This can also result in an interesting but benign issue called 'who ate my variable'. See who ate my variable

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文