(如何)Java JIT编译器优化我的代码?

Rin*_*nke 17 java jit compiler-optimization

我正在编写相当低级别的代码,必须对速度进行高度优化.每个CPU周期都很重要.因为代码是用Java编写的,所以我不能像C中那样写低级别,但是我希望能够从VM中获取所有内容.

我正在处理一个字节数组.我的代码有两个部分,我现在主要感兴趣.第一个是:

int key =  (data[i]     & 0xff)
        | ((data[i + 1] & 0xff) <<  8)
        | ((data[i + 2] & 0xff) << 16)
        | ((data[i + 3] & 0xff) << 24);
Run Code Online (Sandbox Code Playgroud)

第二个是:

key = (key << 15) | (key >>> 17);
Run Code Online (Sandbox Code Playgroud)

从性能来看,我猜这些陈述没有按照我的预期进行优化.第二个陈述基本上是一个ROTL 15, key.第一个语句将4个字节加载到int中.0xff如果访问的字节恰好为负,则掩码仅用于补偿由隐式转换为int所产生的添加符号位.这应该很容易转换为高效的机器代码,但令我惊讶的是,如果我删除了掩码,性能会上升.(这当然会破坏我的代码,但我很想知道会发生什么.)

这里发生了什么?最常见的Java VM是否会在JIT期间以期望优秀的C++编译器优化等效C++代码的方式优化此代码?我可以影响这个过程吗?设置-XX:+AggressiveOpts似乎没有区别.

(CPU:x64,平台:Linux/HotSpot)

sol*_*dil 5

我已经在Java中完成了很多性能代码,我甚至直接在Bytecode中编码,足以确定一些事情:JIT是一个带有模糊行为的黑盒子,JIT和编译器非常高效,并且最简单的代码通常会产生最佳性能.

当您考虑JIT的目标时,这是正常的:从任何Java代码中提取最佳性能.当你添加Java是一个非常简单和简单的语言时,简单的代码将被优化,任何进一步的技巧通常都没有好处.

当然,你应该知道一些常见的陷阱和陷阱,但我在你的代码示例中没有看到.如果我要优化您的代码,我会直接进入更高级别:算法.代码的复杂性是多少?可以缓存一些数据吗?使用了什么API?等等......单独从算法技巧中提取出一个看似无穷无尽的性能坑.

如果即使这还不够,如果语言不够快,如果你的机器不够快,如果你的算法不能更快,那么答案就不在于"时钟周期",因为你可能会挤压20效率的百分比,但是当数据增长时,20%将永远不够.为了确保你永远不会(再次)击中性能墙,最终的答案在于可扩展性:使您的算法和数据无限可分配,这样您就可以让更多的工作人员完成任务.