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

时间:2022-09-28 22:30:34

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.

他们俩都做了同样的事情。确定该方法很热并编译它而不是解释。使用OSR,您只需在编译后立即转移到编译版本,这与JIT不同,后者在第二次调用方法时调用编译代码。

Other than this, are there any other differences?

除此之外,还有其他差异吗?

3 个解决方案

#1


44  

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).

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

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)是一种用于在相同功能的不同实现之间切换的技术。例如,您可以使用OSR在完成编译后立即从已解释或未优化的代码切换到JITed代码。

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

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.

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

#2


8  

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.

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

#3


2  

People already mentioned what is JIT.

人们已经提到了什么是JIT。

on-stack replacement (OSR)

堆叠替换(OSR)

When the JVM executes a Java method, it checks the sum of the number of times the method has been called, and the number of times any loops in the method have branched back and decides whether or not the method is eligible for compilation. If it is, the method is queued for compilation.This kind of compilation has no official name but is often called standard compilation.

当JVM执行Java方法时,它会检查方法被调用的次数的总和,以及方法中任何循环已经分支的次数,并确定该方法是否符合编译条件。如果是,则该方法排队等待编译。这种编译没有正式名称,但通常称为标准编译。

But what if the method has a really long loop—or one that never exits and provides all the logic of the program? In that case, the JVM needs to compile the loop without waiting for a method invocation. So every time the loop completes an execution, the branching counter is incremented and inspected. If the branching counter has exceeded its individual threshold, then the loop (and not the entire method) becomes eligible for compilation. This kind of compilation is called on-stack replacement (OSR), because even if the loop is compiled, that isn’t sufficient: the JVM has to have the ability to start executing the compiled version of the loop while the loop is still running. When the code for the loop has finished compiling, the JVM replaces the code (on-stack), and the next iteration of the loop will execute the much-faster compiled version of the code.

但是,如果该方法有一个非常长的循环,或者一个永不退出并提供程序的所有逻辑的循环怎么办?在这种情况下,JVM需要编译循环而不等待方法调用。因此,每次循环完成执行时,分支计数器都会递增并检查。如果分支计数器已超过其个别阈值,则循环(而不是整个方法)符合编译条件。这种编译称为堆栈替换(OSR),因为即使编译循环,这还不够:JVM必须能够在循环仍在运行时开始执行循环的编译版本。当循环代码完成编译时,JVM将替换代码(on-stack),循环的下一次迭代将执行更快的代码编译版本。

#1


44  

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).

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

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)是一种用于在相同功能的不同实现之间切换的技术。例如,您可以使用OSR在完成编译后立即从已解释或未优化的代码切换到JITed代码。

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

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.

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

#2


8  

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.

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

#3


2  

People already mentioned what is JIT.

人们已经提到了什么是JIT。

on-stack replacement (OSR)

堆叠替换(OSR)

When the JVM executes a Java method, it checks the sum of the number of times the method has been called, and the number of times any loops in the method have branched back and decides whether or not the method is eligible for compilation. If it is, the method is queued for compilation.This kind of compilation has no official name but is often called standard compilation.

当JVM执行Java方法时,它会检查方法被调用的次数的总和,以及方法中任何循环已经分支的次数,并确定该方法是否符合编译条件。如果是,则该方法排队等待编译。这种编译没有正式名称,但通常称为标准编译。

But what if the method has a really long loop—or one that never exits and provides all the logic of the program? In that case, the JVM needs to compile the loop without waiting for a method invocation. So every time the loop completes an execution, the branching counter is incremented and inspected. If the branching counter has exceeded its individual threshold, then the loop (and not the entire method) becomes eligible for compilation. This kind of compilation is called on-stack replacement (OSR), because even if the loop is compiled, that isn’t sufficient: the JVM has to have the ability to start executing the compiled version of the loop while the loop is still running. When the code for the loop has finished compiling, the JVM replaces the code (on-stack), and the next iteration of the loop will execute the much-faster compiled version of the code.

但是,如果该方法有一个非常长的循环,或者一个永不退出并提供程序的所有逻辑的循环怎么办?在这种情况下,JVM需要编译循环而不等待方法调用。因此,每次循环完成执行时,分支计数器都会递增并检查。如果分支计数器已超过其个别阈值,则循环(而不是整个方法)符合编译条件。这种编译称为堆栈替换(OSR),因为即使编译循环,这还不够:JVM必须能够在循环仍在运行时开始执行循环的编译版本。当循环代码完成编译时,JVM将替换代码(on-stack),循环的下一次迭代将执行更快的代码编译版本。