Skip to content

Commit bc26d72

Browse files
committedNov 14, 2019
Add a microbenchmark
1 parent d1b01b0 commit bc26d72

File tree

2 files changed

+151
-2
lines changed

2 files changed

+151
-2
lines changed
 

‎microbenchmarks/loom/run_perf.sh

+5-2
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,8 @@ run_benchmark() {
3737
echo
3838
}
3939

40-
run_benchmark justYield 5 10 15 20 25 30
41-
run_benchmark justContinue 105 110 112 115 120 125 130
40+
run_benchmark baseline 1000
41+
run_benchmark yieldAndContinue 1000
42+
43+
# run_benchmark justYield 5 10 15 20 25 30
44+
# run_benchmark justContinue 105 110 112 115 120 125 130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
package org.openjdk.benchmarks.cont;
25+
26+
import java.util.concurrent.TimeUnit;
27+
import org.openjdk.jmh.annotations.*;
28+
29+
@BenchmarkMode(Mode.AverageTime)
30+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
31+
@State(Scope.Thread)
32+
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
33+
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
34+
@Fork(1)
35+
public class FreezeAndThaw {
36+
static final ContinuationScope SCOPE = new ContinuationScope() { };
37+
38+
static class Arg {
39+
volatile int field;
40+
}
41+
42+
/**
43+
* A recursive task that optionally yields when the stack gets to a specific
44+
* depth. If continued after yielding, it runs to completion.
45+
*/
46+
static class Yielder implements Runnable {
47+
private final int paramCount;
48+
private final int maxDepth;
49+
private final boolean yieldAtLimit;
50+
51+
private Yielder(int paramCount, int maxDepth, boolean yieldAtLimit) {
52+
if (paramCount < 1 || paramCount > 3)
53+
throw new IllegalArgumentException();
54+
this.paramCount = paramCount;
55+
this.maxDepth = maxDepth;
56+
this.yieldAtLimit = yieldAtLimit;
57+
}
58+
59+
@Override
60+
public void run() {
61+
switch (paramCount) {
62+
case 1: run1(maxDepth); break;
63+
case 2: run2(maxDepth, new Arg()); break;
64+
case 3: run3(maxDepth, new Arg(), new Arg()); break;
65+
default: throw new Error("should not happen");
66+
}
67+
}
68+
69+
private void run1(int depth) {
70+
if (depth > 0) {
71+
run1(depth - 1);
72+
} if (depth == 0) {
73+
if (yieldAtLimit) Continuation.yield(SCOPE);
74+
}
75+
}
76+
77+
private void run2(int depth, Arg arg2) {
78+
if (depth > 0) {
79+
run2(depth - 1, arg2);
80+
} if (depth == 0) {
81+
if (yieldAtLimit) Continuation.yield(SCOPE);
82+
} else {
83+
// never executed
84+
arg2.field = 0;
85+
}
86+
}
87+
88+
private void run3(int depth, Arg arg2, Arg arg3) {
89+
if (depth > 0) {
90+
run3(depth - 1, arg2, arg3);
91+
} if (depth == 0) {
92+
if (yieldAtLimit) {
93+
Continuation.yield(SCOPE);
94+
}
95+
} else {
96+
// never executed
97+
arg2.field = 0;
98+
arg3.field = 0;
99+
}
100+
}
101+
102+
static Continuation continuation(int paramCount, int maxDepth,
103+
boolean yieldAtLimit) {
104+
Runnable task = new Yielder(paramCount, maxDepth, yieldAtLimit);
105+
return new Continuation(SCOPE, 2000, task);
106+
}
107+
}
108+
109+
@Param({"1", "2", "3"})
110+
public int paramCount;
111+
112+
@Param({"5", "10", "20", "100"})
113+
public int stackDepth;
114+
115+
Continuation cont;
116+
Continuation cont0;
117+
118+
@Setup(Level.Invocation)
119+
public void setup() {
120+
// System.out.println("pc = " + paramCount + " sd = " + stackDepth);
121+
cont = Yielder.continuation(paramCount, stackDepth, true);
122+
cont0 = Yielder.continuation(paramCount, stackDepth, false);
123+
}
124+
125+
/**
126+
* Creates and runs a continuation that yields at a given stack depth.
127+
*/
128+
@Benchmark
129+
public void baseline() {
130+
// Continuation cont0 = Yielder.continuation(paramCount, stackDepth, false);
131+
cont0.run();
132+
assert cont0.isDone();
133+
}
134+
135+
/**
136+
* Creates and runs a continuation that yields at a given stack depth.
137+
*/
138+
@Benchmark
139+
public void yieldAndContinue() {
140+
// Continuation cont = Yielder.continuation(paramCount, stackDepth, true);
141+
cont.run();
142+
assert !cont.isDone();
143+
cont.run();
144+
assert cont.isDone();
145+
}
146+
}

0 commit comments

Comments
 (0)
Please sign in to comment.