Mercurial > hg > gc-bench
changeset 35:c65e5eaf3b0d
runtime.read|write tests.
author | shade |
---|---|
date | Fri, 02 Dec 2016 17:15:56 +0100 |
parents | 73d0b304ec43 |
children | 0844352df50d |
files | src/main/java/org/openjdk/gcbench/GCBench.java src/main/java/org/openjdk/gcbench/runtime/reads/Plain.java src/main/java/org/openjdk/gcbench/runtime/reads/Volatile.java src/main/java/org/openjdk/gcbench/runtime/reads/fields/Plain.java src/main/java/org/openjdk/gcbench/runtime/reads/fields/Volatile.java src/main/java/org/openjdk/gcbench/runtime/writes/Plain.java src/main/java/org/openjdk/gcbench/runtime/writes/Volatile.java src/main/java/org/openjdk/gcbench/tests/DimensionType.java src/main/java/org/openjdk/gcbench/tests/DimensionValues.java src/main/java/org/openjdk/gcbench/tests/DimensionalTest.java src/main/java/org/openjdk/gcbench/tests/Dimensions.java src/main/java/org/openjdk/gcbench/tests/MachineCntTest.java src/main/java/org/openjdk/gcbench/tests/Sequence.java src/main/java/org/openjdk/gcbench/util/Sinks.java |
diffstat | 14 files changed, 700 insertions(+), 292 deletions(-) [+] |
line wrap: on
line diff
--- a/src/main/java/org/openjdk/gcbench/GCBench.java Fri Dec 02 14:21:19 2016 +0100 +++ b/src/main/java/org/openjdk/gcbench/GCBench.java Fri Dec 02 17:15:56 2016 +0100 @@ -5,8 +5,6 @@ import joptsimple.OptionSpec; import org.openjdk.gcbench.tests.*; import org.openjdk.jmh.annotations.Threads; -import org.openjdk.jmh.profile.GCProfiler; -import org.openjdk.jmh.profile.SafepointsProfiler; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.*; import org.openjdk.jmh.util.Utils; @@ -93,8 +91,6 @@ Options opts = new OptionsBuilder() .detectJvmArgs() .threads(Threads.MAX) - .addProfiler(GCProfiler.class) - .addProfiler(SafepointsProfiler.class) .verbosity(VerboseMode.SILENT) .shouldFailOnError(true) .build(); @@ -126,8 +122,8 @@ .warmupIterations(3) .warmupTime(TimeValue.seconds(1)) .measurementIterations(1) - .measurementTime(TimeValue.seconds(10)) - .forks(1) + .measurementTime(TimeValue.seconds(3)) + .forks(3) .build(); break; case tough: @@ -279,6 +275,42 @@ Dimensions.size(Sequence.powersOfTen_Sub(100, 100000)) )); } + + { + String groupDescr = "Estimates the runtime overhead for reads. These costs include all the infrastructural " + + "overheads too, and therefore the score differences matter, not their absolute values. This test " + + "is single-threaded. "; + + tests.add(new MachineCntTest(baseOpts, org.openjdk.gcbench.runtime.reads.Plain.class, + "runtime.reads.plain", groupDescr + "Reads plain Java fields.", + Dimensions.jvmMode(), + Dimensions.javaType() + )); + + tests.add(new MachineCntTest(baseOpts, org.openjdk.gcbench.runtime.reads.Volatile.class, + "runtime.reads.volatile", groupDescr + "Reads volatile Java fields.", + Dimensions.jvmMode(), + Dimensions.javaType() + )); + } + + { + String groupDescr = "Estimates the runtime overhead for цкшеуы. These costs include all the infrastructural " + + "overheads too, and therefore the score differences matter, not their absolute values. This test " + + "is single-threaded. "; + + tests.add(new MachineCntTest(baseOpts, org.openjdk.gcbench.runtime.writes.Plain.class, + "runtime.writes.plain", groupDescr + "Writes plain Java fields.", + Dimensions.jvmMode(), + Dimensions.javaType() + )); + + tests.add(new MachineCntTest(baseOpts, org.openjdk.gcbench.runtime.writes.Volatile.class, + "runtime.writes.volatile", groupDescr + "Writes volatiel Java fields.", + Dimensions.jvmMode(), + Dimensions.javaType() + )); + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/org/openjdk/gcbench/runtime/reads/Plain.java Fri Dec 02 17:15:56 2016 +0100 @@ -0,0 +1,97 @@ +package org.openjdk.gcbench.runtime.reads; + +import org.openjdk.jmh.annotations.*; + +import java.util.concurrent.TimeUnit; + +import static org.openjdk.gcbench.util.Sinks.sink; + +@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@Fork(1) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Threads(1) +@State(Scope.Benchmark) +public class Plain { + + Target target; + + @Setup + public void setup() { + target = new Target(); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_none() { + sink(); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_boolean() { + sink(target.f_boolean); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_byte() { + sink(target.f_byte); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_char() { + sink(target.f_char); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_short() { + sink(target.f_short); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_int() { + sink(target.f_int); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_float() { + sink(target.f_float); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_long() { + sink(target.f_long); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_double() { + sink(target.f_double); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_Object() { + sink(target.f_Object); + } + + static class Target { + boolean f_boolean; + byte f_byte; + short f_short; + char f_char; + int f_int; + float f_float; + long f_long; + double f_double; + Object f_Object; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/org/openjdk/gcbench/runtime/reads/Volatile.java Fri Dec 02 17:15:56 2016 +0100 @@ -0,0 +1,97 @@ +package org.openjdk.gcbench.runtime.reads; + +import org.openjdk.jmh.annotations.*; + +import java.util.concurrent.TimeUnit; + +import static org.openjdk.gcbench.util.Sinks.sink; + +@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@Fork(1) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Threads(1) +@State(Scope.Benchmark) +public class Volatile { + + Target target; + + @Setup + public void setup() { + target = new Target(); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_none() { + sink(); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_boolean() { + sink(target.f_boolean); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_byte() { + sink(target.f_byte); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_char() { + sink(target.f_char); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_short() { + sink(target.f_short); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_int() { + sink(target.f_int); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_float() { + sink(target.f_float); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_long() { + sink(target.f_long); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_double() { + sink(target.f_double); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_Object() { + sink(target.f_Object); + } + + static class Target { + volatile boolean f_boolean; + volatile byte f_byte; + volatile short f_short; + volatile char f_char; + volatile int f_int; + volatile float f_float; + volatile long f_long; + volatile double f_double; + volatile Object f_Object; + } + +}
--- a/src/main/java/org/openjdk/gcbench/runtime/reads/fields/Plain.java Fri Dec 02 14:21:19 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -package org.openjdk.gcbench.runtime.reads.fields; - -import org.openjdk.jmh.annotations.*; - -import java.util.concurrent.TimeUnit; - -@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) -@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) -@Fork(1) -@BenchmarkMode(Mode.AverageTime) -@OutputTimeUnit(TimeUnit.NANOSECONDS) -@Threads(1) -@State(Scope.Benchmark) -public class Plain { - - Target target; - - @Setup - public void setup() { - target = new Target(); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_boolean() { - sink(target.f_boolean); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_byte() { - sink(target.f_byte); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_char() { - sink(target.f_char); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_short() { - sink(target.f_short); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_int() { - sink(target.f_int); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_float() { - sink(target.f_float); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_long() { - sink(target.f_long); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_double() { - sink(target.f_double); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_Object() { - sink(target.f_Object); - } - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(boolean i) {} - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(byte i) {} - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(short i) {} - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(char i) {} - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(int i) {} - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(float i) {} - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(long i) {} - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(double i) {} - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(Object i) {} - - static class Target { - boolean f_boolean; - byte f_byte; - short f_short; - char f_char; - int f_int; - float f_float; - long f_long; - double f_double; - Object f_Object; - } - -}
--- a/src/main/java/org/openjdk/gcbench/runtime/reads/fields/Volatile.java Fri Dec 02 14:21:19 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -package org.openjdk.gcbench.runtime.reads.fields; - -import org.openjdk.jmh.annotations.*; - -import java.util.concurrent.TimeUnit; - -@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) -@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) -@Fork(1) -@BenchmarkMode(Mode.AverageTime) -@OutputTimeUnit(TimeUnit.NANOSECONDS) -@Threads(1) -@State(Scope.Benchmark) -public class Volatile { - - Target target; - - @Setup - public void setup() { - target = new Target(); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_boolean() { - sink(target.f_boolean); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_byte() { - sink(target.f_byte); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_char() { - sink(target.f_char); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_short() { - sink(target.f_short); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_int() { - sink(target.f_int); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_float() { - sink(target.f_float); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_long() { - sink(target.f_long); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_double() { - sink(target.f_double); - } - - @Benchmark - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - public void test_Object() { - sink(target.f_Object); - } - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(boolean i) {} - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(byte i) {} - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(short i) {} - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(char i) {} - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(int i) {} - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(float i) {} - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(long i) {} - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(double i) {} - - @CompilerControl(CompilerControl.Mode.DONT_INLINE) - private void sink(Object i) {} - - static class Target { - volatile boolean f_boolean; - volatile byte f_byte; - volatile short f_short; - volatile char f_char; - volatile int f_int; - volatile float f_float; - volatile long f_long; - volatile double f_double; - volatile Object f_Object; - } - -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/org/openjdk/gcbench/runtime/writes/Plain.java Fri Dec 02 17:15:56 2016 +0100 @@ -0,0 +1,96 @@ +package org.openjdk.gcbench.runtime.writes; + +import org.openjdk.jmh.annotations.*; + +import java.util.concurrent.TimeUnit; + +import static org.openjdk.gcbench.util.Sinks.sink; + +@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@Fork(1) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Threads(1) +@State(Scope.Benchmark) +public class Plain { + + Target target; + + @Setup + public void setup() { + target = new Target(); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_none() { + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_boolean() { + target.f_boolean = true; + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_byte() { + target.f_byte = 42; + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_char() { + target.f_char = 'A'; + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_short() { + target.f_short = 42; + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_int() { + target.f_int = 42; + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_float() { + target.f_float = 42f; + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_long() { + target.f_long = 42L; + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_double() { + target.f_double = 42D; + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_Object() { + target.f_Object = target; + } + + static class Target { + boolean f_boolean; + byte f_byte; + short f_short; + char f_char; + int f_int; + float f_float; + long f_long; + double f_double; + Object f_Object; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/org/openjdk/gcbench/runtime/writes/Volatile.java Fri Dec 02 17:15:56 2016 +0100 @@ -0,0 +1,96 @@ +package org.openjdk.gcbench.runtime.writes; + +import org.openjdk.jmh.annotations.*; + +import java.util.concurrent.TimeUnit; + +import static org.openjdk.gcbench.util.Sinks.sink; + +@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@Fork(1) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Threads(1) +@State(Scope.Benchmark) +public class Volatile { + + Target target; + + @Setup + public void setup() { + target = new Target(); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_none() { + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_boolean() { + target.f_boolean = true; + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_byte() { + target.f_byte = 42; + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_char() { + target.f_char = 'A'; + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_short() { + target.f_short = 42; + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_int() { + target.f_int = 42; + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_float() { + target.f_float = 42f; + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_long() { + target.f_long = 42L; + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_double() { + target.f_double = 42D; + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void test_Object() { + target.f_Object = target; + } + + static class Target { + volatile boolean f_boolean; + volatile byte f_byte; + volatile short f_short; + volatile char f_char; + volatile int f_int; + volatile float f_float; + volatile long f_long; + volatile double f_double; + volatile Object f_Object; + } + +}
--- a/src/main/java/org/openjdk/gcbench/tests/DimensionType.java Fri Dec 02 14:21:19 2016 +0100 +++ b/src/main/java/org/openjdk/gcbench/tests/DimensionType.java Fri Dec 02 17:15:56 2016 +0100 @@ -10,6 +10,10 @@ THREADS("Threads"), + JVM_MODE("Mode"), + + JAVA_TYPE("Type"), + ; private final String label;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/org/openjdk/gcbench/tests/DimensionValues.java Fri Dec 02 17:15:56 2016 +0100 @@ -0,0 +1,41 @@ +package org.openjdk.gcbench.tests; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +class DimensionValues { + Object[] values; + + public static List<DimensionValues> product(Dimension... dimensions) { + List<DimensionValues> values = new ArrayList<>(); + + for (Dimension d : dimensions) { + List<DimensionValues> nextValues = new ArrayList<>(); + if (values.isEmpty()) { + for (Object v : d.seq()) { + nextValues.add(new DimensionValues(new Object[]{v})); + } + } else { + for (DimensionValues vs : values) { + for (Object v : d.seq()) { + nextValues.add(vs.addNew(v)); + } + } + } + values = nextValues; + } + return values; + } + + + public DimensionValues(Object[] values) { + this.values = values; + } + + DimensionValues addNew(Object value) { + Object[] nv = Arrays.copyOf(values, values.length + 1); + nv[nv.length - 1] = value; + return new DimensionValues(nv); + } +}
--- a/src/main/java/org/openjdk/gcbench/tests/DimensionalTest.java Fri Dec 02 14:21:19 2016 +0100 +++ b/src/main/java/org/openjdk/gcbench/tests/DimensionalTest.java Fri Dec 02 17:15:56 2016 +0100 @@ -1,5 +1,7 @@ package org.openjdk.gcbench.tests; +import org.openjdk.jmh.profile.GCProfiler; +import org.openjdk.jmh.profile.SafepointsProfiler; import org.openjdk.jmh.results.Result; import org.openjdk.jmh.results.RunResult; import org.openjdk.jmh.runner.Runner; @@ -8,9 +10,6 @@ import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; import java.util.Map; public class DimensionalTest extends AbstractTest { @@ -56,35 +55,39 @@ "TTSP (sum, 99%, 99.9%, 99.99%)" ); - int lastKeyVal = -1; + Object lastKeyVal = null; - for (DimensionValues values : product()) { + for (DimensionValues values : DimensionValues.product(dimensions)) { ChainedOptionsBuilder builder = new OptionsBuilder() .parent(baseOpts) + .addProfiler(GCProfiler.class) + .addProfiler(SafepointsProfiler.class) .include(benchmark.getName()); int heapSize = -1; int lds = -1; - int keyVal = -1; + Object keyVal = -1; for (int i = 0; i < dimensions.length; i++) { Dimension d = dimensions[i]; - int value = values.values[i]; + Object value = values.values[i]; if (i == dimensions.length - 2) { keyVal = value; } + int intValue = Integer.valueOf(value.toString()); + switch (d.type()) { case HEAPSIZE: builder = builder.jvmArgsAppend("-Xmx" + value + "m", "-Xms" + value + "m"); - heapSize = value; + heapSize = intValue; break; case LDS: builder = builder.param("ldsMB", String.valueOf(value)); - lds = value; + lds = intValue; break; case THREADS: - builder = builder.threads(value); + builder = builder.threads(intValue); break; case SIZE: builder = builder.param("size", String.valueOf(value)); @@ -138,7 +141,7 @@ private void runWith(DimensionValues values, Options opts, int rate) { pw.print(" "); - for (int v : values.values) { + for (Object v : values.values) { pw.printf("%-10s ", v); } @@ -199,39 +202,4 @@ } } - private List<DimensionValues> product() { - List<DimensionValues> values = new ArrayList<>(); - - for (Dimension d : dimensions) { - List<DimensionValues> nextValues = new ArrayList<>(); - if (values.isEmpty()) { - for (int v : d.seq()) { - nextValues.add(new DimensionValues(new int[]{v})); - } - } else { - for (DimensionValues vs : values) { - for (int v : d.seq()) { - nextValues.add(vs.addNew(v)); - } - } - } - values = nextValues; - } - return values; - } - - private static class DimensionValues { - int[] values; - - public DimensionValues(int[] values) { - this.values = values; - } - - DimensionValues addNew(int value) { - int[] nv = Arrays.copyOf(values, values.length + 1); - nv[nv.length - 1] = value; - return new DimensionValues(nv); - } - } - }
--- a/src/main/java/org/openjdk/gcbench/tests/Dimensions.java Fri Dec 02 14:21:19 2016 +0100 +++ b/src/main/java/org/openjdk/gcbench/tests/Dimensions.java Fri Dec 02 17:15:56 2016 +0100 @@ -27,4 +27,11 @@ return new Dimension(DimensionType.THREADS, Sequence.powersOfTwo(1, Runtime.getRuntime().availableProcessors())); } + public static Dimension jvmMode() { + return new Dimension(DimensionType.JVM_MODE, Sequence.jvmModes()); + } + + public static Dimension javaType() { + return new Dimension(DimensionType.JAVA_TYPE, Sequence.javaType()); + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/org/openjdk/gcbench/tests/MachineCntTest.java Fri Dec 02 17:15:56 2016 +0100 @@ -0,0 +1,137 @@ +package org.openjdk.gcbench.tests; + +import org.openjdk.jmh.profile.LinuxPerfNormProfiler; +import org.openjdk.jmh.results.Result; +import org.openjdk.jmh.results.RunResult; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.ChainedOptionsBuilder; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.Map; + +public class MachineCntTest extends AbstractTest { + + private final Dimension[] dimensions; + + public MachineCntTest(Options baseOpts, Class<?> benchmark, String label, String description, + Dimension... dimensions) { + super(baseOpts, label, benchmark, description); + this.dimensions = dimensions; + } + + @Override + protected void doRun() { + pw.println(" Test dimensions: "); + for (Dimension d : dimensions) { + pw.print(" "); + pw.println(d.toString()); + } + pw.println(); + + pw.print(" "); + + for (Dimension d : dimensions) { + pw.printf("%-30s ", d.label()); + } + + pw.printf("%-35s %-25s %-25s %-25s %n", + "Performance", + "Instructions", + "Cycles", + "Branches" + ); + + Object lastKeyVal = null; + + for (DimensionValues values : DimensionValues.product(dimensions)) { + ChainedOptionsBuilder builder = new OptionsBuilder() + .parent(baseOpts) + .threads(1) + .addProfiler(LinuxPerfNormProfiler.class); + + + Object keyVal = -1; + for (int i = 0; i < dimensions.length; i++) { + Dimension d = dimensions[i]; + Object value = values.values[i]; + if (i == dimensions.length - 2) { + keyVal = value; + } + + switch (d.type()) { + case JVM_MODE: + builder = builder.jvmArgsAppend(String.valueOf(value)); + break; + case JAVA_TYPE: + builder = builder.include(benchmark.getName() + ".test_" + value); + break; + default: + throw new IllegalStateException("Unknown dimension: " + d); + } + } + + if (lastKeyVal != keyVal) { + pw.println(); + lastKeyVal = keyVal; + } + + runWith(values, builder.build()); + } + } + + private void runWith(DimensionValues values, Options opts) { + pw.print(" "); + + for (Object v : values.values) { + pw.printf("%-30s ", v); + } + + try { + RunResult result = new Runner(opts).runSingle(); + + Result prim = result.getPrimaryResult(); + Map<String, Result> sec = result.getSecondaryResults(); + + pw.printf("%-35s %-25s %-25s %-25s%n", + shortVal(prim), + shortVal(sec.get("instructions")), + shortVal(sec.get("cycles")), + shortVal(sec.get("branches")) + ); + } catch (RunnerException e) { + pw.print("FAILED: "); + Throwable cause = e.getCause(); + if (cause != null) { + for (Throwable t : cause.getSuppressed()) { + pw.print(t.getMessage() + " "); + } + } else { + pw.println(" unknown error"); + e.printStackTrace(pw); + } + pw.println(); + } + } + + private String shortVal(Result r) { + if (r != null) { + if (!Double.isNaN(r.getScoreError())) { + return String.format("%.3f ± %.3f %s", r.getScore(), r.getScoreError(), r.getScoreUnit()); + } else { + return String.format("%.3f %s", r.getScore(), r.getScoreUnit()); + } + } else { + return "-"; + } + } + + private String latencyVal(Result r) { + if (r != null && !Double.isNaN(r.getScore())) { + return String.format("%.3f %s", r.getScore(), r.getScoreUnit()); + } else { + return "-"; + } + } +}
--- a/src/main/java/org/openjdk/gcbench/tests/Sequence.java Fri Dec 02 14:21:19 2016 +0100 +++ b/src/main/java/org/openjdk/gcbench/tests/Sequence.java Fri Dec 02 17:15:56 2016 +0100 @@ -1,16 +1,17 @@ package org.openjdk.gcbench.tests; import java.util.ArrayList; +import java.util.Arrays; import java.util.Iterator; import java.util.List; -public class Sequence implements Iterable<Integer> { +public class Sequence implements Iterable<Object> { private final String descr; - private final List<Integer> vals; + private final List<Object> vals; public static Sequence powersOfTen_Sub(int min, int max) { - List<Integer> vs = new ArrayList<>(); + List<Object> vs = new ArrayList<>(); for (int v = min; v <= max; v *= 10) { for (int t = 1; t <= 5; t++) { int n = v * t * 2; @@ -23,7 +24,7 @@ } public static Sequence powersOfTen(int min, int max) { - List<Integer> vs = new ArrayList<>(); + List<Object> vs = new ArrayList<>(); for (int v = min; v <= max; v *= 10) { vs.add(v); } @@ -31,7 +32,7 @@ } public static Sequence powersOfTwo(int min, int max) { - List<Integer> vs = new ArrayList<>(); + List<Object> vs = new ArrayList<>(); for (int v = min; v <= max; v *= 2) { vs.add(v); } @@ -39,7 +40,7 @@ } public static Sequence steps(int min, int max, int steps) { - List<Integer> vs = new ArrayList<>(); + List<Object> vs = new ArrayList<>(); int stepSize = (max - min) / steps; for (int v = min; v <= max; v += stepSize) { vs.add(v); @@ -47,13 +48,13 @@ return new Sequence("[" + min + ", " + max + "], step size = " + stepSize, vs); } - private Sequence(String descr, List<Integer> vals) { + private Sequence(String descr, List<Object> vals) { this.descr = descr; this.vals = vals; } @Override - public Iterator<Integer> iterator() { + public Iterator<Object> iterator() { return vals.iterator(); } @@ -61,4 +62,31 @@ public String toString() { return descr; } + + public static Sequence jvmModes() { + return new Sequence("available JVM modes", + Arrays.asList( + "-Xint", + "-XX:TieredStopAtLevel=1", +// "-XX:TieredStopAtLevel=2", +// "-XX:TieredStopAtLevel=3", + "-XX:TieredStopAtLevel=4" + )); + } + + public static Sequence javaType() { + return new Sequence("Java types", + Arrays.asList( + "none", + "boolean", + "byte", + "short", + "char", + "int", + "float", + "long", + "double", + "Object" + )); + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/org/openjdk/gcbench/util/Sinks.java Fri Dec 02 17:15:56 2016 +0100 @@ -0,0 +1,37 @@ +package org.openjdk.gcbench.util; + +import org.openjdk.jmh.annotations.CompilerControl; + +public class Sinks { + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public static void sink() {} + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public static void sink(boolean i) {} + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public static void sink(byte i) {} + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public static void sink(short i) {} + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public static void sink(char i) {} + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public static void sink(int i) {} + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public static void sink(float i) {} + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public static void sink(long i) {} + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public static void sink(double i) {} + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public static void sink(Object i) {} + +}