Java 6中的线程优化真的有效么?——第二部分 - 编程入门网
Java 6中的线程优化真的有效么?——第二部分时间:2011-05-20 infoq.com Jeroen Borgers 译:韩锴在本文的第一部分中,我们通过一个单一线程的基准,比较了同步的 StringBuffer和非同步的StringBuilder之间的性能。从最初的基准测试结果来看 ,偏向锁提供了最佳的性能,比其他的优化方式更有效。测试的结果似乎表明获 取锁是一项昂贵的操作。但是在得出最终的结论之前,我决定先对结果进行检验 :我请我的同事们在他们的机器上运行了这个测试。尽管大多数结果都证实了我 的测试结果,但是有一些结果却完全不同。在本文的第二部分中,我们将更深入 地看一看用于检验测试结果的技术。最后我们将回答现实中的问题:为什么在不 同的处理器上的锁开销差异如此巨大? 基准测试中的陷阱 通过一个基准测试,尤其是一个“小规模基准测试”(microbenchmark),来 回答这个问题是非常困难的。多半情况下,基准测试会出现一些与你期望测量的 完全不同的情景。即使当你要测量影响这个问题的因素时,结果也会被其他的因 素所影响。有一点在这个实验开始之初就已经很明确了,即这个基准测试需要由 其他人全面地进行审查,这样我才能避免落入报告无效基准测试数据的陷阱中。 除了其他人的检查以外,我还使用了一些工具和技术来校验结果,这些我会在下 面的几节中谈到。 结果的统计处理 大多数计算机所执行的操作都会在某一固定的时间内完成。就我的经验而言, 我发现即使是那些不确定性的操作,在大多数条件下基本上也能在固定的时间内 完成。正是根据计算的这种特性,我们可以使用一种工具,它通过测量让我们了 解事情何时开始变得不正常了。这样的工具是基于统计的,其测量结果会有些出 入。这就是说,即使看到了一些超过正常水平的报告值,我也不会做过多过的解 释的。原因是这样的,如果我提供了指令数固定的CPU,而它并没有在相对固定的 时间内完成的话,就说明我的测量受到了一些外部因素的影响。如果测试结果出 现了很大的异常,则意味着我必须找到这个外部的影响进而解决它。 尽管这些异常效果会在小规模基准测试中被放大,但它不至于会影响大规模的 基准测试。对于大规模的基准测试来说,被测量的目标应用程序的各个方面会彼 此产生干扰,这会带来一些异常。但是异常仍然能够提供一些很有益的信息,可 以帮助我们对干扰级别作出判断。在稳定的负荷下,我并不会对个别异常情况感 到意外;当然,异常情况不能过多。对于那些比通常结果大一些或小一些的结果 ,我会观察测试的运行情况,并将它视为一种信号:我的基准测试尚未恰当地隔 离或者设置好。这样对相同的测试进行不同的处理,恰恰说明了全面的基准测试 与小规模基准测试之间的不同。 最后一点,到此为止仍然不能说明你所测试的就是你所想的。这至多只能说明 ,对于最终的问题,这个测试是最有可能是正确的。 预热方法的缓存 JIT会编译你的代码,这也是众多影响基准测试的行为之一。Hotspot会频繁地 检查你的程序,寻找可以应用某些优化的机会。当找到机会后,它会要求 JIT编 译器重新编译问题中的某段代码。此时它会应用一项技术,即当前栈替换(On Stack Replacement,OSR),从而切换到新代码的执行上。执行OSR时会对测试产 生各种连锁影响,包括要暂停线程的执行。当然,所有这样的活动都会干扰到我 们的基准测试。这类干扰会使测试出现偏差。我们手头上有两款工具,可以帮助 我们标明代码何时受到JIT的影响了。第一个当然是测试中出现的差异,第二个是 -XX:-PrintCompilation标记。幸运的是,如果不是所有的代码在测试的早期就进 行JIT化处理,那么我们可以将它视为另外一种启动时的异常现象。我们需要做的 就是在开始测量前,先不断地运行基准测试 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |