Live data from Hacker News

Ahead-of-Time Compilation

bugs.openjdk.java.net

51–60 of 95 posts

Re: Ahead-of-Time Compilation

#51
post #34
post #18

This is great news, though it initially only supports Linux x86-64 and is decades late for Java desktop apps (and not having non-blocking I/O until Java 1.4 was shameful for a language explicitly targeted and a pervasively networked ecosystem.) In their "tiered mode", they put sampling instrumentation into the native code, and if they detect a hotspot, regenerate fully instrumented native code from bytecode using the…

> decades late for Java desktop apps Commercial JDKs always offered AOT compilation, the problem is that people nowadays apparently don't buy compilers anymore unless forced to do so (e.g. embedded, consoles...).

There has also been gcj for a long time, but default toolchains matter a lot.

Re: Ahead-of-Time Compilation

#52
post #6

Earlier quoted context omitted.

A JIT can use information from runtime for optimizations, you pay a cost in startup time. Being worse or better depends on the workloads and implementations.

AOT can as well. PGO.

Yes, but that locks you in to optimising for whatever you covered with your profiling. If the character of your data changes, it'll take a recompile to change how the application performs, while a JIT can potentially choose to deoptimise/reoptimise.

I'm all for "as static as possible" toolchains, but there are optimization opportunities you simply won't have with AOT, PGO or not. E.g. consider something trivial: A program doing certain image operations that depends on dimensions passed in on the command line. A JIT could optimise the inner loops for the actual operations. To get the same with AOT even with PGO would be totally unable to deal with it without causing a massive explosion in code size.

Re: Ahead-of-Time Compilation

#53
post #46
post #18

This is great news, though it initially only supports Linux x86-64 and is decades late for Java desktop apps (and not having non-blocking I/O until Java 1.4 was shameful for a language explicitly targeted and a pervasively networked ecosystem.) In their "tiered mode", they put sampling instrumentation into the native code, and if they detect a hotspot, regenerate fully instrumented native code from bytecode using the…

LLVM bitcode is still architecture specific - for example, whether the code is 64 bit or 32 bit will result in different bitcode paths. You may be interested to look further into Eclipse OMR, which is a generic VM used by IBM for many of their runtimes (including J9). The Testarossa JIT support landed last week, and although it doesn't support bitcode form directly there are optimisations that can be used to transfor…

Thanks for the pointer!

I (and others) have noted that for more than a decade, it seems that Java would have been better off under IBM than under Sun/Oracle (SWT vs. Swing/AWT, jikes vs. javac, Jalapeno/JikesRVM vs. not much interesting research until Graal, etc.) It's really a shame IBM didn't buy up Sun's Java intellectual property at fire sale prices.

Re: Ahead-of-Time Compilation

#54
post #52

Earlier quoted context omitted.

AOT can as well. PGO.

Yes, but that locks you in to optimising for whatever you covered with your profiling. If the character of your data changes, it'll take a recompile to change how the application performs, while a JIT can potentially choose to deoptimise/reoptimise. I'm all for "as static as possible" toolchains, but there are optimization opportunities you simply won't have with AOT, PGO or not. E.g. consider something trivial: A pr…

Hence why .NET also has MPGO, Managed Profile Guided Optimizations for NGEN.

https://msdn.microsoft.com/en-us/library/hh873180(v=vs.110)....

Re: Ahead-of-Time Compilation

#55
post #4

I'm not familiar enough with compilers, but why would an ahead of time compiler perform worse than a just in time compiler in a static language? I think I'd understand if it was a dynamic language, because you can't know the types for sure until you start running the program, but are similar issues present for Java?

Most of the JIT optimizations amount to "it's been called like this in the past; assume it'll always be & depotimize (at a penalty) if it isn't." That potentially includes the fully resolved types of objects (ie devirtualization), branch prediction (stronger than the CPU can do; for instance, if a value is only used inside a branch that's never taken, don't bother mutating it), data sizes (this "array" is only ever s…

> assume it'll always be & depotimize (at a penalty) if it isn't

Stuff like this makes me nervous. Performance is already a complex topic, and stuff like this makes it even more complex. Unnecessarily so. If we were talking about a very high-level programming language (say, Prolog), you could argue that the expressiveness benefits outweigh the cost of the runtime system's complexity. But Java isn't even as expressive as C++, let alone Prolog.

> fully resolved types of objects (ie devirtualization)

C++ (and similar languages: D, Rust, etc.) and MLton (a Standard ML implementation) have been using monomorphization for ages, which is a compile-time analogue of devirtualization. Moreover, monomorphization has important advantages over devirtualization:

(0) It's completely predictable. You don't need to guess when it will happen. It happens iff the concrete type (and its relevant vtables, if necessary) can be determined at compile-time: https://blog.rust-lang.org/2015/05/11/traits.html

(1) It's always a sound optimization, so it doesn't have to be undone at runtime under any circumstances.

(2) It's relatively simple to implement. In fact, a compiler front-end can completely monomorphize a program before handing it over to the back-end for target code generation.

> if a value is only used inside a branch that's never taken, don't bother mutating it)

The best way to handle unreachable branches is to avoid creating them in the first place. With proper use of algebraic data types and pattern matching, unreachable branches can be kept to a minimum, or even outright eliminated in many cases.

> data sizes (this "array" is only ever size 2, store it in registers)

C and similar languages natively handle statically sized arrays, so there's no need for runtime profiling and analysis just to determine that an array will always have size 2.

ML does something even better: you just use tuples (in this case, pairs), which reflect your intent much better than using arrays whose size has to be tested or guessed.

---

What I take away from this is that the JVM's supposedly “fancy” optimizations exist primarily to work around the Java language's lack of amenability to static analysis.

Re: Ahead-of-Time Compilation

#56
post #51
post #34

Earlier quoted context omitted.

> decades late for Java desktop apps Commercial JDKs always offered AOT compilation, the problem is that people nowadays apparently don't buy compilers anymore unless forced to do so (e.g. embedded, consoles...).

There has also been gcj for a long time, but default toolchains matter a lot.

I seem to recall that GCJ had a lot of limitations back in the day - you couldn't use the same standard library, it didn't support newer language features, etc. Wouldn't surprise me if even now GCJ had poor integrations with IDEs and other essential tools to make Java livable.

Re: Ahead-of-Time Compilation

#57
post #9

Assuming this comes in Java 9, and compilation of code other `java.base` is possible, will this make Java a more solid competitor to Go? I guess it partly depends on how much they optimize the compiled binary size. Go does a really good job at static compilation, so it will be tough to compete.

Go still has the feature of lightweight threads (goroutines) by default and great communication and synchronization primitives (channels, select) between them. For Java you still have to choose either real threads or from one of dozens of not-necessarily-compatible async IO frameworks (Netty, Grizzly, ...). How much that really matters depends on the type of your application. There's also emulation of Gos concurrency through Quasar - but again it's not as first class as Gos features.

Re: Ahead-of-Time Compilation

#58
post #52

Earlier quoted context omitted.

AOT can as well. PGO.

Yes, but that locks you in to optimising for whatever you covered with your profiling. If the character of your data changes, it'll take a recompile to change how the application performs, while a JIT can potentially choose to deoptimise/reoptimise. I'm all for "as static as possible" toolchains, but there are optimization opportunities you simply won't have with AOT, PGO or not. E.g. consider something trivial: A pr…

In theory yes, but sadly i have never seen that promise realized in any consistent fashion. Same goes for Java's escape analysis. Although the principle is sound i think the engineering required is horrendously difficult to make it robust. In a very narrow window of variation it works, but should you step out of that zone it fails pretty badly. I think it will take many more years, till then pgo and metaprogramming it is.

Re: Ahead-of-Time Compilation

#59
post #38

Earlier quoted context omitted.

I remember that HotSpot was promising faster than GCC -O2. This sort of over promising was good for presentations to the Schmidt and McNealy types.

My understanding is that GCC has a more diverse arsenal of optimizations that it can apply to code while hotspot has the advantage that it can profile at runtime and apply speculative optimizations based on those profiles and bail out later if things change. In principle it can even optimize code that never reaches steady state as long as the transient states last long enough. What costs java performance these days i…

Indeed. Another issue is that java semantics is too rigidly defined. Compilers of many other languages have a lot more room in deciding order of evaluation, vectorization etc
Post reply on HN