Live data from Hacker News

A Deep Introduction to JIT Compilers: JITs are not very Just-in-time

carolchen.me

51–60 of 103 posts

Re: A Deep Introduction to JIT Compilers: JITs are not very Just-in-time

#51
post #5
post #2

Tl;dr: JIT is a compiler that optimuzes certain parts of code after interpreter see it as hot (e.g. was executed many time). Thank to runtime information it can occasionally exceed performance of statically compiled language.

> Thank to runtime information it can occasionally exceed performance of statically compiled language. Interestingly in 30 years I have not once heard of a case where this theoretical benefit has manifested as a clear advantage in any real world application when looking at the system as a whole... amdahls law and all that. You can always hand tune the 1-10% hotspots for reasonable cost most of the time, and even stat…

The way I explain the unreasonable effectiveness of JITs and adaptive compilation (multiple compilers with the advanced ones focusing on the hot spots) is by contrasting constants and variables.

In a long enough time frame nearly everything is variable: over decades even computer architectures and language syntax change. In a short enough time frame nearly everything is constant: in a single cycle a von Neumann computer will only change a single memory location and all the others will have a constant value.

Even though an AOT compiler might have minutes or more to work on a code fragment, the code it generates has to work for a long time and on many different machines. A JIT might have milliseconds or less to work on the same code fragment but what it generates only needs to work on this exact machine and only for minutes or hours. In fact, it might even be wrong and have to be recompiled less than a second after the JIT produced it.

So the code generated by the AOT must treat as variable things that the JIT can pretend are constant (with hook to recompile if it proves not to be so).

This is slightly related to partial evaluation, which is a key idea in Graal.

Re: A Deep Introduction to JIT Compilers: JITs are not very Just-in-time

#52
post #5

Earlier quoted context omitted.

> Thank to runtime information it can occasionally exceed performance of statically compiled language. Interestingly in 30 years I have not once heard of a case where this theoretical benefit has manifested as a clear advantage in any real world application when looking at the system as a whole... amdahls law and all that. You can always hand tune the 1-10% hotspots for reasonable cost most of the time, and even stat…

> in 30 years I have not once heard of a case where this theoretical benefit has manifested as a clear advantage in any real world application Today you make make a very direct empirical comparison to see this - using the Graal compiler. This lets you compile exactly the same Java code either ahead-of-time or just-in-time, but using the same compiler logic except for the runtime information available when running jus…

>> Interestingly in 30 years I have not once heard of a case where this theoretical benefit has manifested as a clear advantage in any real world application when looking at the system as a whole.

> The just-in-time code is (ignoring startup and warmup time) in my experience always faster, due to the extra runtime information.

I don't think that result is surprising. The issue is that in the real world you can't ignore startup and warm up times.

I've never heard the claim that JIT compiled code is slower than statically compiles code. The issue is that the extra costs associated with JIT don't outweigh its benefits.

Re: A Deep Introduction to JIT Compilers: JITs are not very Just-in-time

#54

This article is really nice for not making things harder than they needed to be. Trace then substitute the trace - no magic. It seems like a big part of all these strategies is making sure the checks for the optimizations (checking if they're possible, checking if they're done) don't take more time than the optimizations save. Or could there be a way to alter the execution graph so that once you add in the optimizati…

> It seems like a big part of all these strategies is making sure the checks for the optimizations (checking if they're possible, checking if they're done) don't take more time than the optimizations save.

You can't really check that, you can only hope your heuristics are right. You don't know in advance how many times a method will be executed and thus how much optimization budget is worth it. If you boot up a java application that runs for months and handles tons of traffic then you could theoretically justify many minutes of CPU cycles for optimization.

And that's not all that makes JITs complex. Some also do speculative optimizations that require guards and deoptimization points so they can fallback and recompile if those assumptions are violated. If the language has a garbage collector then the GC and JITs have to cooperate for ideal performance.

Re: A Deep Introduction to JIT Compilers: JITs are not very Just-in-time

#56

There is also an interesting presentation about how Azul implemented their JIT called Falcon, that is fully based on LLVM. https://www.youtube.com/watch?v=Uqch1rjPls8 Generally LLVM is a nice idea that allows vendors to reuse major components.

The one problem with LLVM is that it’s not very well suited to JIT compilers, a major component of which is its slowness.

Re: A Deep Introduction to JIT Compilers: JITs are not very Just-in-time

#58

Is anyone aware of any efforts to get clang/rustc to use lli to speed up iteration times? My thought is you lower everything to llvm bytecode first but skip all the codegen/linking. Then you can codegen or run interpreted. Might help make debug builds much faster to get to execution. Probably could trivially parallelize the background compilation & auto-build in the background on every file change to get the best of…

How much time actually goes into instruction selection and register allocation? I thought a lot of the time went into optimization passes at the IR level.

Re: A Deep Introduction to JIT Compilers: JITs are not very Just-in-time

#59
post #52

Earlier quoted context omitted.

> in 30 years I have not once heard of a case where this theoretical benefit has manifested as a clear advantage in any real world application Today you make make a very direct empirical comparison to see this - using the Graal compiler. This lets you compile exactly the same Java code either ahead-of-time or just-in-time, but using the same compiler logic except for the runtime information available when running jus…

>> Interestingly in 30 years I have not once heard of a case where this theoretical benefit has manifested as a clear advantage in any real world application when looking at the system as a whole. > The just-in-time code is (ignoring startup and warmup time) in my experience always faster, due to the extra runtime information. I don't think that result is surprising. The issue is that in the real world you can't igno…

There are plenty of real world situations where startup and warm up times don't matter.

Re: A Deep Introduction to JIT Compilers: JITs are not very Just-in-time

#60

Earlier quoted context omitted.

I too keep hearing this repeated but without empirical support. Same goes for the idea that garbage collection can be faster than manually managed memory. In practice, PGO has been the best possible compilation regime that I have ever found.

> Same goes for the idea that garbage collection can be faster than manually managed memory. It's really workload dependent and depend a lot of the GC involved (a pretty dumb one like Python's or Go's won't get you anything performance wise), but a copying collector can achieve allocation way faster than a regular heap allocator (the allocation can be almost as cheap as allocating on the stack). If you can't avoid bo…

CPython and Go's allocators are already faster than simple heap allocation using malloc/free.

CPython has a specialized arena allocator for small allocations called obmalloc.

Go's allocator is descended from tcmalloc but faster because it doesn't need to support the free(1) api and all the book-keeping required.

Post reply on HN