在对Java应用程序进行基准测试时,如何补偿没有“安静”的机器?

问题描述 投票:4回答:1

我一直在进行数值模拟。我可以判断我的模拟是否不起作用(即,它们无法给出可接受的答案),但是因为我通常在后台运行的指定核心上运行可变数量的这些(当我工作时),查看时钟时间告诉我关于他们跑得多快的事情还不算什么。

我不想要时钟;我想要CPU时间。没有一篇文章似乎提到这个小方面。特别是,使用“安静”机器的建议似乎模糊了所测量的内容。

我不需要太多细节,我只是想知道模拟A比模拟B或C快15%或更慢,尽管事实上A运行了一段时间,然后我开始B,然后是C.也许我在退休之前玩了一会儿,这将在一段时间内运行更高优先级的应用程序。不要告诉我理想情况下我应该使用“安静”的机器;我的问题专门询问如何在没有专用机器的情况下进行基准测试。我也不希望在测量应用程序运行时间的同时降低应用程序的效率;似乎只有在需要大量细节时才需要大量开销。我对吗?

我想修改我的应用程序,以便在检查批处理作业是否成功时,我还可以看到在CPU时间内达到这些结果需要多长时间。基准测试能给我找到我想要的答案吗?我可以简单地使用Java 9的基准测试工具,还是需要其他东西?

java performance benchmarking java-9
1个回答
4
投票

在大多数操作系统上,您可以轻松地从JVM外部测量CPU时间而不是挂钟时间。例如Unix / Linux上的time java foo.jar,甚至是Linux上的perf stat java foo.jar

最大的问题是某些工作负载比其他工作负载更具并行性。考虑这个简单的例子。这是不现实的,但对于在更多并行和不太并行的阶段之间交替的真实程序,数学运算是相同的。

  • 版本A纯粹连续9分钟,并保持8个核心饱和1分钟。挂钟时间= 10分钟,CPU时间= 17分钟
  • 版本B是串行1分钟,并保持所有8个核心忙5分钟。挂起时间= 6分钟,CPU时间= 5 * 8 + 1 = 41分钟

如果你只是在查看CPU时间,你就不会知道哪个版本在其工作的固有连续部分中被卡住了。 (这假设纯粹是CPU绑定的,没有I / O等待。)

但是,对于两个大多数都是串行的类似实现,CPU时间和挂起时间可以给你一个合理的猜测。

但是像HotSpot这样的现代JVM使用多线程垃圾收集,所以即使你自己的代码永远不会启动多个线程,一个使GC做更多工作的版本可以使用更多的CPU时间但仍然更快。但这可能很少见。


另一个混淆因素:争用内存带宽和缓存占用空间意味着需要更多的CPU时间来完成相同的工作,因为您的代码将花费更多的时间等待内存。

使用HyperThreading或其他SMT cpu架构(如Ryzen),其中一个物理内核可以充当多个逻辑内核,同时使两个逻辑内核都活跃,从而以降低每线程性能为代价提高总吞吐量。

因此,在HT兄弟空闲的核心上,1分钟的CPU时间可以完成更多的工作,当另一个逻辑核心也处于活动状态时。

在两个逻辑核心都处于活动状态的情况下,现代Skylake或Ryzen可能会为单核心提供所有执行资源的50%到99%的单线程性能,完全取决于每个线程上运行的代码。 (如果FP的延迟的瓶颈加上并且与非常长的循环携带的依赖链相乘,那么无序执行无法看到过去,例如,对于严格的FP,按顺序求和非常大的数组,这是HT的最佳情况两个线程都不会减慢另一个线程,因为FP增加吞吐量是3到8倍FP添加延迟。)

但在最糟糕的情况下,如果两个任务从L1d缓存未命中缓慢减缓很多,HT甚至可以在同一个核心上同时运行两个任务,而不是运行一个然后另一个运行。

© www.soinside.com 2019 - 2024. All rights reserved.