如何使用JMH对随机访问进行基准测试?

时间:2019-03-18 22:05:22

标签: java cpu-cache jmh cache-locality

我试图通过使用JMH对数组的顺序/随机读取进行基准测试来观察CPU缓存空间局部性的影响。有趣的是,结果几乎相同。

所以我想知道,这是正确的JMH方法吗?

下面是我使用的测试课程

@OutputTimeUnit(TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
@OperationsPerInvocation(MyBenchmark.N)
public class MyBenchmark {

    /*
     * # JMH version: 1.21
     * # VM version: JDK 1.8.0_91, Java HotSpot(TM) 64-Bit Server VM, 25.91-b15
     * # VM invoker: D:\jdk1.8.0_91\jre\bin\java.exe
     * # VM options: <none>
     * # Warmup: 5 iterations, 10 s each
     * # Measurement: 5 iterations, 10 s each
     * # Timeout: 10 min per iteration
     * # Threads: 1 thread, will synchronize iterations
     * # Benchmark mode: Average time, time/op
     * 
     * Benchmark                 Mode  Cnt  Score   Error  Units
     * MyBenchmark.randomAccess  avgt   25  7,930 ± 0,378  ns/op
     * MyBenchmark.serialAccess  avgt   25  7,721 ± 0,081  ns/op
     */
    static final int N = 1_000;

    @State(Scope.Benchmark)
    public static class Common {

        int[] data = new int[N];
        int[] serialAccessOrder = new int[N];
        int[] randomAccessOrder = new int[N];

        public Common() {
            Random r = new Random(11234);
            for (int i=0; i<N; i++) {
                data[i] = r.nextInt(N);
                serialAccessOrder[i] = i;
                randomAccessOrder[i] = data[i];
            }
        }
    }

    @Benchmark
    public void serialAccess(Blackhole bh, Common common) {
        for (int i=0; i<N; i++) {
            bh.consume(common.data[common.serialAccessOrder[i]]);
        }
    }

    @Benchmark
    public void randomAccess(Blackhole bh, Common common) {
        for (int i=0; i<N; i++) {
            bh.consume(common.data[common.randomAccessOrder[i]]);
        }
    }
}

更新: 结果发现N太小(1_000 * 4字节/整数〜= 4KB)很可能整个数组都被缓存了。将N增加到1_000_000可获得更直观的结果:

Benchmark                 Mode  Cnt   Score   Error  Units
MyBenchmark.randomAccess  avgt   25  20,426 ± 0,678  ns/op
MyBenchmark.serialAccess  avgt   25   6,762 ± 0,252  ns/op

0 个答案:

没有答案
相关问题