(This is more of a potential improvement than a bug – I'm not really sure if this is the appropriate place for it).
I was profiling a mod I was working on, and found that I was getting a lot of branch mispredicts in Minecraft's perlin noise generator, in particular the gradient function. I was able to eliminate some of the branches, to get a 2.5% time reduction in world gen. (Obviously I'm working with decompiled code – hopefully in this case it is similar enough to your code that you can tell what I'm talking about).
In the gradient function, the return statement is something like this:
return ((perm & 1) == 0 ? x : -x) + ((perm & 2) == 0 ? y : -y);
which costs you one branch mispredict per function call on average (since perm is random). It can be replaced with this:
int flip1 = -((perm & 1) << 1) + 1;
int flip2 = -(perm & 2) + 1;
return flip1*x + flip2*y;
which gets most of the speed increase I mentioned. Earlier in the function you branch on the condition:
perm != 12 && perm != 14
which can be slightly improved to:
(perm | 0x2) != 14
In theory the compiler could then compile the remaining branches down into conditional moves, thus eliminating branch mispredict costs altogether, however it doesn't seem to be able to generate floating-point conditional move instructions at the moment (integer conditional move works fine).
Environment
Java version: 1.7.0_45 (IcedTea 2.4.3) (Gentoo build 1.7.0_45-b31)
CPU: Intel(R) Core(TM) i5-3570 CPU @ 3.40GHz (64bit)
OS: Funtoo Linux (64bit)
Comments 4
Another small improvement: replacing
double x = perm < 8 ? param2 : param3;
with
int b = perm >> 3;
double x = (1-b)*param2 + b0*param3;
brings the total time reductions up to 9.3%. I also tried completely debranching the function – unfortunately without the ability to generate setnz or movcc instructions, it was worse than nothing.
Thanks, Kyle! Your optimizations look good and we've rolled them into the code.
Technically, as it's not a "bug", we have to mark the bug as Invalid in order to close it out, so don't worry! If you end up with any other optimizations, especially involving ways to appease the branch predictor, feel free to e-mail them to me directly at [email protected] so you don't have to go through Mojira again. 🙂
Thanks again!
When possible, see if this applies to 1.7.*, as the world generator for these versions has been completely redone.