使用Java和JMH对无锁堆栈进行基准测试

时间:2019-02-25 20:15:28

标签: java multithreading concurrency benchmarking jmh

对于我的一门大学课程,我需要实现一个无锁的堆栈实现,并对其执行基准测试,以查看它在线程数和操作分配方面如何扩展。我最近发现了JMH,并想将其应用于作业分配的基准测试部分。我只是不确定我是否会尽可能优雅地实现这一点。

我的教授希望我们测量1、2、4、8、16和32个线程执行3种不同操作分布所花费的时间。我在下面建模:

package kylemart.multicore.assignment2;

import org.openjdk.jmh.annotations.*;

// Annotations here... 
public class P1StackBenchmarks {

    @Benchmark
    public void runScenarioA(ScenarioA scenario) throws InterruptedException {
        runThreads(scenario.threads);
    }

    @Benchmark
    public void runScenarioB(ScenarioB scenario) throws InterruptedException {
        runThreads(scenario.threads);
    }

    @Benchmark
    public void runScenarioC(ScenarioC scenario) throws InterruptedException {
        runThreads(scenario.threads);
    }

    private void runThreads(Thread[] threads) throws InterruptedException {
        for (Thread thread : threads) {
            thread.start();
        }
        for (Thread thread : threads) {
            thread.join();
        }
    }

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

        @Param({"1", "2", "4", "8", "16", "32"})
        int threadCount;

        static final int iterations = 500_000;
    }

    @State(Scope.Thread)
    public static abstract class Scenario {

        Thread[] threads;
        PStack<Object> stack;
        Object object;

        @Setup(Level.Invocation)
        public void setup(BenchmarkParameters params) {
            threads = new Thread[params.threadCount];
            stack = new P1Stack<>();
            object = new Object();
            Runnable runnable = () -> {
                for (int iteration = 0; iteration < params.iterations; iteration++) {
                    operations();
                }
            };
            for (int index = 0; index < threads.length; index++) {
                threads[index] = new Thread(runnable);
            }
        }

        protected abstract void operations();
    }

    public static class ScenarioA extends Scenario {

        @Override
        protected void operations() {
            // stack.push(object);
            // ...
        }
    }

    public static class ScenarioB extends Scenario {

        @Override
        protected void operations() {
            // stack.push(object);
            // ...
        }
    }

    public static class ScenarioC extends Scenario {

        @Override
        protected void operations() {
            // stack.push(object);
            // ...
        }
    }
}

每种情况A,B和C都有一种operations()方法,该方法定义了一组具有特定频率pop()push()和{{1} }电话。抽象的Scenario类是这些特定方案的“模板”。假设注解是可继承的(似乎是这种情况–尽管不介意有人对此进行检查),我希望这三个具体的Scenario类的实例的作用域为单个线程(即size() ),并使其@State(Scope.Thread)方法在每次调用基准方法(即setup())之前运行。这样,我就可以在开始运行线程之前对每个方案的线程进行构造和设置。

此实现有任何问题吗? JMH中是否还有其他设施可以使此问题更易于解决/实施?谢谢!

0 个答案:

没有答案
相关问题