CPU costs of Thread.sleep() and Thread.onSpinWait()
I'm running two benchmarks in order to compare costs of Thread.sleep()
and Thread.onSpinWait()
:
@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class ThreadSleep2Benchmark {
private final ExecutorService executor = Executors.newFixedThreadPool(1);
volatile boolean run;
@Param({"1", "5", "10", "50", "100"})
long delay;
@Setup(Level.Invocation)
public void setUp() {
run = true;
startThread();
}
@TearDown(Level.Trial)
public void tearDown() {
executor.shutdown();
}
@Benchmark
public int sleep() throws Exception {
while (run) {
Thread.sleep(1);
}
return hashCode();
}
private void startThread() {
executor.submit(() -> {
try {
Thread.sleep(delay / 2);
run = false;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
});
}
}
Then I run the one with Thread.onSpinWait()
:
@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class ThreadOnSpinWaitBenchmark {
private final ExecutorService executor = Executors.newFixedThreadPool(1);
volatile boolean run;
@Param({"1", "5", "10", "50", "100"})
long delay;
@Setup(Level.Invocation)
public void setUp() {
run = true;
startThread();
}
@TearDown(Level.Trial)
public void tearDown() {
executor.shutdown();
}
@Benchmark
public int onSpinWait() {
while (run) {
Thread.onSpinWait();
}
return hashCode();
}
private void startThread() {
executor.submit(() -> {
try {
Thread.sleep(delay / 2);
run = false;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
});
}
}
Both demonstrate nearly same results for delay > 1 ms:
Benchmark (delay) Mode Cnt Score Error Units
ThreadOnSpinWaitBenchmark.onSpinWait 1 avgt 20 0,003 ± 0,001 ms/op
ThreadOnSpinWaitBenchmark.onSpinWait 5 avgt 20 2,459 ± 0,027 ms/op
ThreadOnSpinWaitBenchmark.onSpinWait 10 avgt 20 5,957 ± 0,064 ms/op
ThreadOnSpinWaitBenchmark.onSpinWait 50 avgt 20 27,915 ± 0,225 ms/op
ThreadOnSpinWaitBenchmark.onSpinWait 100 avgt 20 53,112 ± 0,343 ms/op
ThreadSleep2Benchmark.sleep 1 avgt 20 1,420 ± 0,043 ms/op
ThreadSleep2Benchmark.sleep 5 avgt 20 3,183 ± 0,099 ms/op
ThreadSleep2Benchmark.sleep 10 avgt 20 6,723 ± 0,069 ms/op
ThreadSleep2Benchmark.sleep 50 avgt 20 29,697 ± 0,307 ms/op
ThreadSleep2Benchmark.sleep 100 avgt 20 54,730 ± 0,329 ms/op
This is quite expected.
I'd like however to measure CPU load of both approaches. I know that on Linux I can use LinuxPerfNormProfiler
but I'm not sure which particular metric I should take to get reliable insight.
Comments
Post a Comment