giltene
perhaps someone should advertise AVX2 and AVX512 under the tag "It's not you father's numeric-processing-focused vectorization"
As for the charts in the blog post: yes, it's a depiction. The Y axis gains will vary by application, obviously. And we've seen that gain range form a few % to high 10s of %s with real workloads, measured by real customers who use them. Use cases span a wide range, including databases, in-memory query engines, search and indexing, protocol gateways, stream processing, messaging, analytics, and matching engines. None are things that classically make you think "numeric processing", BTW.
As to the AVX2 work contributed: there are all sorts of "easier to integrate" AVX2 uses that had been added to HotSpot over time (especially with intrinsics, which tend to be nice and isolated from the rest of the code gen), but the vectorizer in C2 is not nearly as capable as the one in LLVM, and the results speak for themselves. And I expect o see a similar gap open when AVX512 becomes available on Skylake EPs soon.
On the "how many contributions directly applicable to Java vs. C++ question": we were surprised at how readily those "C++ focused things" apply to idiomatic java code. The LLVM contributions can probably be better describes as "expecting certain patterns and idioms that are common in C/C++". And once you bring the Java code to LLVM IR form and "remove the breaks" as much as possible (e.g. fix how things like safepoints, GC barriers, and depot points used to defeat most optimizations), the patterns seem to be there in the Java code as well. The vectorization u-bench thing here is certainly a good example of that in play. We didn't massage it to find the vectorization opportunity. I didn't even get specific directions or tips on "write it this way". I just wrote some "I think this loop should be vectorizeable with AVX2" pieces of java code and the existing vectorizer seemed to have just picked them up and had its way with them.
Enjoy!
- The reason Zing tends to to carry higher throughput in production is that in most Java-based systems, production throughput levels are limited not by system capacity, but by how far you can drive the JVMs before the glitches start being unbearable, and what looks like occasional small hiccups at lower throughputs starts looking more like epileptic seizures at load. Capacity planning and sizing usually aim to keep peak production loads below the levels that lead to these "I don't want to go there" behaviors. By taking out the various glitching/pausing/stalling behaviors typically associated with JVMs under load, Zing extends the smooth operating range such that it comes much closer to the traditional "how much can this hardware handle?" capacity and sizing behavior people are used to in non-Java and non-GC'ed environments.
- When you compare raw throughput or speed (with no SLAs, e.g. "how long does this multi-hour batch job take to complete?"), with similar configurations Zing is usually comparable to OpenJDK/HotSpot [Where comparable typically means within +/-15-20% range. Sometimes faster, sometimes slower.] But once people apply simple knob twists in the applications (like turning up heap sizes, caches, and other using-memory-no-longer-hurts related settings) they often get more raw throughout per instance or machine through simple efficiency benefits (like the elimination of raw work that comes from higher in-process, on-heap cache hit rates).
Well, you heard wrong.
Zing is used in plenty of throughput-intesive and throughout-centric applications, and sustainable throughput on Zing tends to be higher (not lower) than with other JVMs. E.g. Cassandra clusters tend to carry higher production loads per machine when powered by Zing (compared to OpenJDK or HotSpot on the same hardware). All while dramatically improving their latency behavior and consistency.
Specifically, on similarly sized heaps and workloads, the C4 collector's throughout is better than CMS's and close to ParallelGC's. And since it's throughput scales linearly with the amount of empty heap configured and since (unlike OpenJDK/Hotspot) Zing places no practical pause-related caps on how much memory can be applied, it tends to beat both on efficiency in actual configurations.
The notion that good latency behavior has to come at the expense of throughput is just a silly myth. There are plenty of examples that disprove it. Zing/C4 is just one of many.
Whatever it is you think you figured out about how C4 works seems to be wrong. You may want to re-examine those fundamentals.
Just because it may also be possible to use page remapping to save on toilet paper or rescue kittens doesn't mean that's what we do with it. We do what we say we do. No conjecture needed.
1. We never claimed the algorithm uses "techniques unknowable by others" (um, we published the algorithm, so it's obviously knowable by others)
2. We never claimed to have implemented generic transactional memory using regular x86 primitives.
So you can consider this made up hype countered.
You seem to conflate Vega's [very cool] hardware transactional memory capabilities (SMA, OTC) with GC. Vega never used transactional memory for GC purposes. It used transactional memory to support OTC and transparent concurrent execution of synchronized blocks. Nothing to do with GC, and nothing to do with C4.
And yes. I can assertively "claim" that the page mapping and protection schemes in C4 are not analogous to the transactional memory support in Vega, and have nothing to do with caches or memory controllers. Vega (just like C4 on x86) used page mapping and protection schemes for GC purposes.
Well. One of us is wrong.
I created the C4 algorithm. And I wrote the paper. I'm pretty sure I know what it does.
:-)
You raise another "I think this is how it works and therefore it must be slow" point in this posting that you didn't raise before, so let me address it to avoid confusion:
> "...Page remapping is insanely expensive at the micro-granularity needed."
If you actually read the paper (e.g. Table 2), you would have realize that C4 uses a page remapping mechanism that (in 2011) could sustain >700TB/sec of page remapping speed. Using my recommendation that remapping rate needs to be able to handle 100x the allocation rate, that's enough to keep up with 7TB/sec of allocation. So I think we have some headroom. The number have only gotten better since with Zing's loadable module.
Zing is certainly cheaper than the engineering time it offsets. If you feel that you need to avoid using Zing at all costs, you can certainly avoid using it by spending shitloads of your best talent, time, and effort (which are presumably not free) to successfully force your apps only run at 300MB/sec on those 20GB/sec-capable Xeons you paid shitloads of money for, and to dramatically under-utilize them. That's certainly a choice.
I'm pretty sure one shitload is bigger than the other. The whole trick is to pay with the smaller pile.
- C4 makes no use of hardware transactional memory.
- C4 works great (and natively) on commodity x86-64 cores.
- C4 does not emulate anything (not memory architecture, not HTM).
- C4's transactional throughput kicks ass.
If you want to know how C4 works, all you need to do is read the actual C4 ISMM paper: http://www.azulsystems.com/sites/default/files/images/c4_pap... <And yes, I'm one of the authors>
How you got to your posted conclusions from the link you posted is a mystery to me. Cliff doesn't say anything much about the GC mechanism there: he is talking about lessons learned in designing custom hardware. And yes, Vega had some cool GC-assist features, but they are in no way part of the C4 collector mechanism.
Since you raised the bogus, unsubstantiated assertion that "[Zing's] transactional throughput in the vast majority of workloads sucks" based purely on your mis-interpretation of what C4 actually does, I feel I must correct that notion.
To do that, I'll point out that Zing (with C4) is currently used, in production, to run some of the highest transactional throughput and most latency sensitive applications in the world. Zing's sustainable throughput (the throughput at which the system still meets the required SLA) is generally dramatically better than other JVMs running on exactly the same modern x86 hardware. Yes, you read that right: Zing gets more production-worthy TPS out of the same x86 hardware. Not less.
This is why people who actually need good throughput and good latency tend to graduate to using Zing, and start enjoying time in their hammocks as a result. See http://mail.openjdk.java.net/pipermail/hotspot-gc-use/2014-O... for a happy example.
C4 is being used in everything from low latency trading (Algo, HFT, smart routing wire risk) to Online Retail (think black Friday workloads) and travel sites. C4 is used for everything from 1GB compute-heavy and messgaing workloads to 1TB data-heavy analysts applications. It powers big data workloads. It powers search. It powers Java servers of all kinds, big and small. And none of those are complaining about throughput. Quite the opposite.
Peace.
OpenJDK is just source code. Binaries (built by various companies and orgs) comes from someplace else, and are usually called something else. E.g. RedHat calls theirs "IcedTea". Azul calls their binary distro of OpenJDK "Zulu".
When you get a binary build of OpenJDK from some place (in tar/zip form, or deb or rpm package form), some of those are well built and tested (e.g. Azul's Zulu and RedHat's IcedTead, and obviously Oracle's own JDKs). But some may not be. they may just be a random build from a random point in the source tree, using unknown tool chains and shipped with little or notesting. E.g. the Java 8 version you'd currently get on the experimental debian:sid repos is base don 8u40: a source tree that is still in flux and not planned to be released as 8u40 until March of 2015.
Many people care about running on a JDK version that was actually tested and verified. Right now Zulu is the only binary build of a Java 8 OpenJDK that meets that need. And on MacOS or Windows, it's the only one for 7 and 6 as well.
On x86, if you can measure performance diffs between same-version OpenJDK/Zulu and OracleJDK, you are probably measuring noise. Zulu is simply a binary build of OpenJDK. As far as we can tell, the performance is identical because the source is the same.
For MacOS and Windows, Zulu is the only binary distro of OpenJDK that I am aware of. For Linux (as of this writing), Zulu is the only publicly available binary distro of OpenJDK 8 that actually undergoes TCK testing and Java SE compatibility testing. [RedHat provides 7 and 6 binaries through the IcedTea project, but IcedTea has not yet shipped a Java 8 version].
So unless you want to build OpenJDK from source (and test top verify what you built is good), you'll need to get a binary from somewhere. Zulu is that somewhere.
To demonstrate the simple value of a tested and certified binary build: The current default Java binary thing you get on docker's official Java runtime image for Java 8 is 8u40 (https://registry.hub.docker.com/_/java/). But 8u40 doesn't actually exist. It is still in development in OpneJDK and won't be released until March 2015. So this thing you pull off a repo is certainly not a tested or released version (likely a top of tree snapshot built from source and just pushed to an experimental repo).
For a current list of companies and organizations that are actually able to fully test OpenJDK 8 (or 7, or 6), see the TCK signatories list at: http://openjdk.java.net/groups/conformance/JckAccess/jck-acc...
<< And yes, I work for Azul. >>