3 ms·
The article seems to ignore a variety of very real benefits that you get from the JIT. In many real world cases, there are optimizations that the JIT can perfor
by yummyfajitas 11y ago
The article seems to ignore a variety of very real benefits that you get from the JIT. In many real world cases, there are optimizations that the JIT can perform. For example:
final boolean runF = ...; //In *this* program run, it works out to be false.
...
if (runF) {
f(x);
}
The JIT can just eliminate this branch entirely. More interestingly:
if (cond) {
myVar = f(x); //f(x) has provably no side effects
}
Supposing cond is nearly always true, the JIT can optimistically run f and in parallel check cond. In the unlikely event that cond is false, the JIT will still compute the return value of f(x), but just not do the assignment.
It surprised me when I saw all this happen, but the JVM's JIT is actually pretty smart and works very well for long running server processes.
- xyzzyz 11y agoIn the first case, either the "if" is run in a tight loop, and then the branch predictor will likely predict it correcly, or it isn't, and then branch elimination brings only trivial improvement. In the second, what do you mean by "run f and in parallel check cond"? How that would translate to the machine code? You want to run and synchronize cond and f(x) between two separate CPU cores or what?
- yummyfajitas 11y agoAnd if it's not run in a tight loop, the JIT can often still detect it. I don't know why you believe such things are trivial. On one occasion I altered some code which broke this, and it added about 10-20 seconds to a 15 minute HFT simulation. If that code made it to prod, those 10-20 seconds would be distributed around the hot parts of an HFT system. That's not remotely trivial, at least for performance critical applications (HFT, RTB, etc). In the second example, basically what happens (if you get lucky - I haven't found the JVM JIT to be super consistent) is that computation of cond and f(x) will be put into the pipeline together, and only the assignment to myVar will be conditional. This is strictly NOT something the CPU can do by itself, since there are side effects at the machine level (allocating objects, and then GCing them).
- tobias3 11y agoThis is also something the CPU's branch predictor can figure out and do the same optimization on. This decreases the benefit from AOT-compiled code.
- chrisseaton 11y ago> This is also something the CPU's branch predictor can figure out and do the same optimisation on The benefit of this optimisation isn't correctly predicting the branch, which is the only thing the CPU branch predictor can do, it's removing the untaken branch from the optimisation pipeline. if (x) { y = rand(); } else { y = 14; } y * 2; In this code if x is never true then not only will the branch not taken be removed, but the code following the if statement can be optimised knowing for sure that y is always the constant 14, and then the whole thing can be constant folded.
- minikomi 11y agoWouldn't the y*2 be the first to be removed completely? :)
- Kristine1975 11y agoNot if the language uses implicit returns, as e.g. Ruby does. Then y * 2 is equivalent to return y * 2 when it is the last statement in the function.
- draw_down 11y agoI don't think it ignores that, just says that such benefits were always smaller in reality than promised, and not worth the lack of predictability WRT performance.