java - 在对我的 Java 应用程序进行基准测试时,如何补偿没有 "quiet"机器的情况?

标签 java performance benchmarking java-9

我一直在运行数值模拟。我可以判断我的模拟是否不起作用(即,它们无法给出可接受的答案),但是因为我通常在后台运行的指定内核上运行可变数量的模拟(当我工作时),查看时钟时间告诉我他们跑得有多快几乎没有。

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

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

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

最佳答案

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

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

  • 版本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 时间,因为您的代码将花费更多的时间等待内存。

在超线程或其他 SMT cpu 架构(如 Ryzen)中,一个物理核心可以充当多个逻辑核心,让两个逻辑核心都处于 Activity 状态会增加总吞吐量,但会降低每线程性能。

因此,与其他逻辑内核也处于 Activity 状态时相比,HT 兄弟空闲的内核上 1 分钟的 CPU 时间可以完成更多的工作。

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

但在最坏的情况下,如果两个任务都因 L1d 缓存未命中而减慢很多,HT 甚至会因为在同一内核上同时运行两个任务而损失吞吐量,而不是先运行一个再运行另一个。

关于java - 在对我的 Java 应用程序进行基准测试时,如何补偿没有 "quiet"机器的情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55604975/

相关文章:

java - JMH:如何避免从抽象基状态共享状态?

scala - 我可以使用哪些工具来对 Scala 代码进行基准测试?

java - 如何从该字符串创建 JSONArray?

java - 如何使用 selenium 和 Java 从 Jenkins 获取测试运行 ID

java - 使用drawRect时图形太慢

performance - PostgreSQL 查询耗时过长

performance - Service Fabric 事务比另一台计算机中的 SQL 事务慢 10 倍

java - Spring Boot i18n 问题

java - 哪个是创建 PageObject 实例的更好方法?

c# - C# 中的基准测试方法调用