JMH Multiple Benchmarks 独立运行的不同结果
JMH Multiple Benchmarks Different results on isolated runs
我 运行 通过 JMH 进行了一些基准测试
假设我在一个 Java 文件中列出了三个基准测试
@Benchmark
@Threads(value = 2)
@Warmup(iterations = 10)
@Fork(value = 2)
@Measurement(iterations = 10)
public String benchmarkA() {
...
}
@Benchmark
@Threads(value = 2)
@Warmup(iterations = 10)
@Fork(value = 2)
@Measurement(iterations = 10)
public String benchmarkB() {
...
}
@Benchmark
@Threads(value = 2)
@Warmup(iterations = 10)
@Fork(value = 2)
@Measurement(iterations = 10)
public String benchmarkC() {
...
}
每种方法都针对服务于相同目的的不同算法进行基准测试。当我 运行 将所有基准测试放在一起时,与 运行 一个一个地测试基准相比,结果有所不同。
例如,在 Java 文件上仅使用 onw 基准执行 JMH 运行。
@Benchmark
@Threads(value = 2)
@Warmup(iterations = 10)
@Fork(value = 2)
@Measurement(iterations = 10)
public String benchmarkA() {
...
}
这种方法的结果会更好如果只有这种方法 运行s,但是在更多基准的情况下,结果会更差。
假设结果明智 benchmarkA > benchmarkB > benchmarkC 通过 运行 将它们隔离开,如果我 运行 将它们全部放在一起,它们之间的差异就会被放大。
我还尝试更改基准测试的顺序(按字典顺序执行),结果是一样的。好像benchmark的数量影响了结果。
可能是什么原因?
每个基准测试都在其自己的 JVM 中执行(除非明确设置为其他行为),因此不应发生交叉基准污染。可能发生并且很常见的是 CPU 的热节流。如果您在无法控制 CPU 频率的环境中进行基准测试,典型的行为是第一个基准测试将 CPU 频率提高,然后基准测试受到限制。您可以在 Linux 环境中控制此变量,方法是切换到用户控制的电源调节器并为您的 CPU.
设置固定频率
确实 CPU 频率的动态缩放可能是导致此问题的原因之一。
我发现这个 issue 对于准备基准测试环境很有帮助。
我 运行 通过 JMH 进行了一些基准测试
假设我在一个 Java 文件中列出了三个基准测试
@Benchmark
@Threads(value = 2)
@Warmup(iterations = 10)
@Fork(value = 2)
@Measurement(iterations = 10)
public String benchmarkA() {
...
}
@Benchmark
@Threads(value = 2)
@Warmup(iterations = 10)
@Fork(value = 2)
@Measurement(iterations = 10)
public String benchmarkB() {
...
}
@Benchmark
@Threads(value = 2)
@Warmup(iterations = 10)
@Fork(value = 2)
@Measurement(iterations = 10)
public String benchmarkC() {
...
}
每种方法都针对服务于相同目的的不同算法进行基准测试。当我 运行 将所有基准测试放在一起时,与 运行 一个一个地测试基准相比,结果有所不同。
例如,在 Java 文件上仅使用 onw 基准执行 JMH 运行。
@Benchmark
@Threads(value = 2)
@Warmup(iterations = 10)
@Fork(value = 2)
@Measurement(iterations = 10)
public String benchmarkA() {
...
}
这种方法的结果会更好如果只有这种方法 运行s,但是在更多基准的情况下,结果会更差。
假设结果明智 benchmarkA > benchmarkB > benchmarkC 通过 运行 将它们隔离开,如果我 运行 将它们全部放在一起,它们之间的差异就会被放大。
我还尝试更改基准测试的顺序(按字典顺序执行),结果是一样的。好像benchmark的数量影响了结果。
可能是什么原因?
每个基准测试都在其自己的 JVM 中执行(除非明确设置为其他行为),因此不应发生交叉基准污染。可能发生并且很常见的是 CPU 的热节流。如果您在无法控制 CPU 频率的环境中进行基准测试,典型的行为是第一个基准测试将 CPU 频率提高,然后基准测试受到限制。您可以在 Linux 环境中控制此变量,方法是切换到用户控制的电源调节器并为您的 CPU.
设置固定频率确实 CPU 频率的动态缩放可能是导致此问题的原因之一。
我发现这个 issue 对于准备基准测试环境很有帮助。