A Race of Two Compilers: GraalVM JIT versus HotSpot JIT C2 [video]
youtube.com
youtube.com
The same app can be run on the JVM or compiled statically using Graal. The JVM version takes around a 100 megs of RAM, and has a significant startup time. The Graal version weighs in at 7 megs, and starts up instantly.
http://bootvis.nl/fastr-sudokus/
Later I ran into some errors which are supposed to be fixed in the development branch but I haven't tested.
.NET is the platform. There are different implementations for it doing different things.
JIT compilation is still different to AOT even without profile guided optimizations. Simple example: In AOT code you can't embed pointers easily and is often solved with indirection (e.g. something like GOT in ELF).
And are they now speculative? They weren't for the first 15 years or so.
It's experimental currently, no profile guided optimizations _yet_
AOT compilers can't afford running optimization passes in a loop (inline, optimize, inline, optimize, ...) until they reach a fixed point because that would blow up compile times if that were applied to the whole program.
An example of this kind of speculation is speculating that there will only ever be one thread in a system, and removing locks. If that speculation ever proves to be wrong - a second thread is created - the locks are put back into the system.
That doesn't related to spectre, as when the speculation is reversed the whole programs is first brought to a safe halt - it isn't fine-grained enough to be useful for Spectre.
Unrelated, it is true that compilers need to be aware of Spectre-like vulnerabilities, and Graal does include experimental support for that.
As long as the compiled code has a check for values that are not 2 this code works great. It isn't correct though.
At least, that's my interpretation.
I think the point is that some JITs never do this kind of optimisation - they just produce the same code an AOT compiler would, but at runtime. Such as the .NET JIT.
Edit: Your example in the other comment about the locks is the sort of thing I'm asking about. There, an optimization is made which is sound under some specific conditions and then unmade when those conditions change.
> (or did, last time I checked)
Do implementations of .NET JITs now do speculative optimisations or dynamic compilation? They didn't see the need for it for about 15 years.
In what concerns the need for it, they have been trying to make C# more relevant for the kinds of C++ workloads and getting among the first places at TechEmpower.
So .NET has been getting Modula-3 like low level handling of value types within a GC environment, RyuJIT is now tiered, supports SIMD and some automatic vectorization.
.NET Framework 4.6 got the first version of what is the .NET way of doing AppCDS.
There are a couple of blog posts regarding RyuJIT improvements with each release after its introduction.
If you read the blog posts, they always talk about speculation being something they may try in the future. I've not seen anything where they say they went ahead and implemented it.
Background JIT overview, which is a kind of PGO for the .NET Frameworok
https://msdn.microsoft.com/en-us/magazine/mt683795.aspx
And I think this goes into line with what you are discussing,
https://github.com/dotnet/coreclr/pull/21270
I also agree that many things remain to be done in line with what Graal is capable of.
Seems like they started trying speculative optimizations about six months ago. Speculative optimizations are not only the foundation of Graal but also of C2, BTW.
If I recall correctly, it will do constant folding, but won't speculate that a certain parameter is always essentially constant at runtime, but wasn't at compile time.
An easy example is a config loaded from a file as the server boots but never changes for the lifetime of the process. That won't constant fold without speculation.
So while it is hard to state what each AOT/JIT compiler is capable of, naturally they aren't 100% all the same.
Of course, the function it compiled will actually not work with any different but still valid arguments, but that's not really trouble since the JIT compiler will simply evaluate that the already compiled version won't work for those as the function is called and compile a new version of the function for the new types just before. A pure ahead-of-time compiler wouldn't be able to optimize so aggressively since it would lead to an exponential explosion of possible inputs combinations most of which will very likely never happen.
Let's say you wanted to optimize a short instruction sequence with a small domain of inputs. You could try to generate all (or at least, zillions) of similarly-sized possible instruction sequences and check them for soundness and performance. Now you're really making soundness guesses. Do real JITs actually make that sort of soundness guess (not that kind of attempt at optimization, obviously)?
I'm mostly talking about production-ready stuff, such work is certainly some fun playground. The Julia JIT (one of the notoriously aggressive JITs, for good and bad), allows users to, at runtime, add new context-aware behaviors to the compiler [1], and people used it for example to experiment with auto-parallelization of code and overall manipulating the code generated by the compiler. That was basically what got me into the language. So you could probably make a library that would inject some weird risky optimization that abuses the type system.
[1] https://docs.google.com/presentation/d/1IiBLVU5Pj-48vzEMnuYE...
Let me give you two common examples: virtual calls and branches. A JIT will speculatively devirtualize and inline a virtual call at a particular callsite if it has only encountered one or a small number of concrete instances, even if it can't prove that those are the only instances that can be encountered at that callsite. This is still sound because the JIT will emit a trap that will trigger if an unknown target is ever encountered, in which case it will deoptimize the compilation, go back to the interpreter and then compile again under new assumptions. Another example is branch elimination. If a JIT only ever encounters the program taking one side of a branch, it will only compile that branch (and introduce a trap), even if it can't prove that only that side will ever be taken.
1. Jettison soundness
2. ???
3. Performance profit.
Which seems like witchcraft, then again JITs are full of witchcraft. But it's also not what you wrote. I've now come to understand the two chief weapons of the JIT remain surprise, fear, ruthless efficiency and an almost fanatical devotion to the Pope.
This will lead to an interesting problem if they want to replace C2 with Graal. Are they willing to regress performance for some open-source-only users, even if it's a performance win for others?
In the end, you should not trust standard benchmarks and definitely not micro-benchmarks. Do perform tests with your own workload.
I've been following Graal for quite some time, both as a former PLDI guy but also for my day job. I work in bioinformatics software (mostly cancer genomics research) and our group has a ton of (mostly legacy) code in Java and R, but most of the newly-minted grads coming in lean towards Python.
As one of the guys pulling all this stuff together, the Graal "polyglot" multilingual VM concept is of tremendous interest as you can imagine. It would be great to be able to package the legacy stuff interoperably with the new stuff no matter the language, even setting aside the bonus of better performance. But it has basically no practical use to us without Python (+ packages!) due to the direction and language inclinations of the group.
Is there anything new happening on that front? Or anything we could do to help it along? Is there more a detailed status page anywhere? Any sense of when this might land in a truly usable form, or what's the hold up?
I'm a bit surprised that the progress with R (with packages) is so far along but the progress with Python (with packages) seems stagnant (at least according to that README). No offense meant to the team, but that's the appearance. Is it the GIL?
[1] https://github.com/graalvm/graalpython, which calls it "early-stage experimental" and "very likely that any Python program that requires any packages at all will hit something unsupported".
Largest project I compiled was only ~1000 lines but used external deps of pymysql, jinja2, ldap3 along with the stdlib's shutil, tempfile, pathlib, and the base os lib without issues. It takes ~30 minutes to compile on a decently powerful machine though (8650u and 32gb of ram). Most of this time was spent on pymysql and jinja2's compilation.
An alternative Python compiler by itself frankly buys us very little. Perhaps Jython, if it weren't targeting 2.7.x.
I've heard that the Twitter JVM team has a road show where they've talked to some other large Scala users about the performance improvements. Initially, people are highly skeptical of the claims, but after trying Graal on their internal workloads, they generally see similar results.
Here's a paper which has some explanations for why you might expect Graal to improve Scala performance: http://aleksandar-prokopec.com/resources/docs/graal-collecti...
http://www.scala-native.org/en/v0.3.9-docs/ https://github.com/scala-native/scala-native
It provides manual memory management as needed, making it suitable for even hard real time applications.
Edit: GraalVM CE describes it on the download page https://www.graalvm.org/downloads/
what is "Improved performance and smaller footprint"? If i use the CE, does it produce worse code somehow?
Java's LTS means something that could perhaps be quite different from LTS in other projects. LTS is a service offered by companies to arbitrary JDK versions of their choice (e.g. Azul offers extended support for versions other than those Oracle does); there is nothing special about the development, testing, effort or focus put into those versions. In addition, people can choose to maintain OpenJDK update projects, as Red Hat does for 11. Anyway, JDK 12 is simply the current JDK version, and there is no reason to use an old version for a technical discussion -- there is nothing more stable about it, or any other technical difference -- even if companies offer extended support for it. (I work on OpenJDK at Oracle)
But two of the main maintainers, Oracle and Red Hat, absolutely do.
> LTS is a service offered by companies to arbitrary JDK versions of their choice
And that arbitrary version is 11.
It's technically accurate but substantially disingenuous to suggest that 11 is not Java's current LTS.
BTW, Oracle contributes ~90% and Red Hat ~5%.
> It's technically accurate but substantially disingenuous to suggest that 11 is not Java's current LTS.
Either way that has little significance here. It is not the most popular version of Java in use today (that would be 8u2XX) nor is it any more production-ready or stable than 12. You can say that we're interested in results for the current version of Java or in the most popular one. I don't understand why it would be particularly interesting to discuss JDK 11, which is neither.
The post itself is interesting on two fronts: as a new emerging technology but also as a leverageable tool. As an OpenJDK developer I understand your interests are more about the former.
For many of us are using Oracle or RedHat LTS builds, we are running either 8 or 11 for "reasons". It's pretty natural to know if these new changes to the platform apply to a given version without asking.