循环调用的Java jits方法,性能大大提高,以后很少运行

时间:2015-08-17 18:48:22

标签: java jvm jit

我正在关注HDFS并注意到它花费了大量时间来验证校验和,并且在几次之后它会大幅加速。 我正在读一个1 MB的文件,并且它执行了17次crc32c校验和,因为该文件被分解为64 KB的数据包。 以下是时间的示例,以秒为单位(最后一个数据包为~16KB):

0.005154
0.005455
0.005836
0.005837
0.005884
0.001014
0.000741
0.000756
0.000718
0.000712
0.000709
0.000712
0.000718
0.000678
0.000677
0.000700
0.000186

我使用-XX:+UnlockDiagnosticVMOptions -XX:+PrintCompilation运行java,并且通常在第二次验证校验和调用之前看到它是jit-ing org.apache.hadoop.util.PureJavaCrc32C#update。 然而,直到第6次通话仍然需要约5ms,当时间开始直线下降。

我制作了一个单独的Java文件来测试它,生成65536字节的随机数据并计算其校验和17次(每次我在512字节块上进行校验和,只是模仿HDFS的行为)。 我刚刚复制了Hadoop的PureJavaCrc32C(上面链接)的源代码。 这是文件http://ideone.com/aY1srS

在我的计算机上,我看到与以前类似的结果(如果我使用-XX:+UnlockDiagnosticVMOptions -XX:+PrintCompilation运行,PureJavaCrc32C#update会在第二次调用之前得到jit-ed,就像在HDFS上一样)

0.010146
0.010859
0.012253
0.006862
0.000237
0.000225
0.000243
0.000244
0.000225
0.000242
0.000241
0.000243
0.000241
0.000241
0.000240
0.000239
0.000241

在ideone.com上,时间实际上在第一次调用后立即下降(可能它使用更积极的编译/执行选项?),但是如果我在tutorialspoint.com上运行,我会看到类似~5毫秒运行的模式然后其余的亚毫秒运行

如果添加-XX:+PrintInlining,我看不到任何新内容。 我还注意到,在前几个缓慢的时间和其余的“快速”时间之间似乎有一个“中间”的运行;在第一组数字中,它从~5ms -> ~1ms -> ~0.7ms下降,在我的计算机上的测试文件中从~10ms -> ~7ms -> ~0.2ms开始,在教程点上它从~4ms -> ~1.5ms -> ~0.1ms

开始

任何人都可以解释这种行为吗? 似乎JIT显然与循环中途的性能增加有很大关系,尽管其他因素可能起作用。 我不知道JIT如何工作的细节,也找不到很多很好的文章/论文解释它,但我想也许在JIT编译了函数之后,应用程序线程需要一段时间来查看和使用原生功能? 此外,如果有人能指出一些好的,深入的JIT论文,那也将受到赞赏

0 个答案:

没有答案