changeset 18:277827642a3e

Rehash fragger.* tests.
author shade
date Tue, 29 Nov 2016 21:09:09 +0100
parents 27e18d65dad9
children 0831a3bb0271
files pom.xml src/main/java/org/openjdk/gcbench/GCBench.java src/main/java/org/openjdk/gcbench/fragger/ArrayFragger.java src/main/java/org/openjdk/gcbench/fragger/LinkedListFragger.java src/main/java/org/openjdk/gcbench/fragger/TreeFragger.java src/main/java/org/openjdk/gcbench/tests/DimensionalTest.java
diffstat 6 files changed, 77 insertions(+), 76 deletions(-) [+]
line wrap: on
line diff
--- a/pom.xml	Tue Nov 29 20:09:29 2016 +0100
+++ b/pom.xml	Tue Nov 29 21:09:09 2016 +0100
@@ -38,7 +38,7 @@
     <version>1.0</version>
     <packaging>jar</packaging>
 
-    <name>JMH benchmark sample: Java</name>
+    <name>GC Benchmarks</name>
 
     <!--
        This is the demo/sample template build script for building Java benchmarks with JMH.
--- a/src/main/java/org/openjdk/gcbench/GCBench.java	Tue Nov 29 20:09:29 2016 +0100
+++ b/src/main/java/org/openjdk/gcbench/GCBench.java	Tue Nov 29 21:09:09 2016 +0100
@@ -212,28 +212,30 @@
         }
 
         {
-            String groupDescr = "Populates heap with data, and randomly overwrites the part of it to cause fragmentation. ";
+            String groupDescr = "Populates heap with data, and randomly overwrites the part of it to cause fragmentation. " +
+                    "The tests are rate-limited to see on what load the collector breaks down. ";
 
             tests.add(new DimensionalTest(baseOpts, org.openjdk.gcbench.fragger.ArrayFragger.class,
                     "fragger.array", groupDescr + "Retains a single large reference array.",
                     true,
-                    Dimensions.heapSize(8),
-                    Dimensions.lds(8)
+                    Dimensions.heapSize(4),
+                    Dimensions.lds(4)
             ));
 
             tests.add(new DimensionalTest(baseOpts, org.openjdk.gcbench.fragger.TreeFragger.class,
                     "fragger.tree", groupDescr + "Retains a binary tree of Nodes.",
                     true,
-                    Dimensions.heapSize(8),
-                    Dimensions.lds(8)
+                    Dimensions.heapSize(4),
+                    Dimensions.lds(4)
             ));
 
-            tests.add(new DimensionalTest(baseOpts, org.openjdk.gcbench.fragger.LinkedListFragger.class,
-                    "fragger.linkedlist", groupDescr + "Retains a LinkedList.",
-                    true,
-                    Dimensions.heapSize(8),
-                    Dimensions.lds(8)
-             ));
+// FIXME: Enable the test back, it runs too slow
+//            tests.add(new DimensionalTest(baseOpts, org.openjdk.gcbench.fragger.LinkedListFragger.class,
+//                    "fragger.linkedlist", groupDescr + "Retains a LinkedList.",
+//                    true,
+//                    Dimensions.heapSize(4),
+//                    Dimensions.lds(4)
+//            ));
         }
 
         {
--- a/src/main/java/org/openjdk/gcbench/fragger/ArrayFragger.java	Tue Nov 29 20:09:29 2016 +0100
+++ b/src/main/java/org/openjdk/gcbench/fragger/ArrayFragger.java	Tue Nov 29 21:09:09 2016 +0100
@@ -1,7 +1,8 @@
 package org.openjdk.gcbench.fragger;
 
-import org.openjdk.gcbench.util.ratelimit.TokenBucket;
+import org.openjdk.gcbench.util.ratelimit.MultiTokenBucket;
 import org.openjdk.jmh.annotations.*;
+import org.openjdk.jol.info.GraphLayout;
 
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
@@ -15,11 +16,8 @@
 @State(Scope.Benchmark)
 public class ArrayFragger {
 
-    @Param({"100"})
-    int size;
-
     @Param({"1000"})
-    int ldsMB;
+    long ldsMB;
 
     @Param({"10"})
     int rate;
@@ -28,35 +26,27 @@
 
     int count;
 
-    TokenBucket bucket;
+    MultiTokenBucket bucket;
+
+    private int getSizePerCount() {
+        return 4 + // array element
+                16; // object
+    }
 
     @Setup
     public void setup() {
-        bucket = new TokenBucket(rate);
-        count = (int)Math.max(1, (1L * ldsMB * 1024 * 1024) / align(16 + 4 + size, 8));
+        bucket = new MultiTokenBucket(rate);
+        count = (int) Math.max(1, ldsMB * 1024 * 1024 / getSizePerCount());
         objects = new Object[count];
         for (int c = 0; c < count; c++) {
-            doStore(c, new byte[size]);
-        }
-    }
-
-    public static int align(int size, int align) {
-        if ((size % align) == 0) {
-            return size;
-        } else {
-            return ((size / align) + 1) * align;
+            objects[c] = new Object();
         }
     }
 
     @Benchmark
     public void test() {
         bucket.limit();
-        doStore(ThreadLocalRandom.current().nextInt(count), new byte[size]);
-    }
-
-    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
-    private void doStore(int idx, byte[] obj) {
-        objects[idx] = obj;
+        objects[ThreadLocalRandom.current().nextInt(count)] = new Object();
     }
 
 }
--- a/src/main/java/org/openjdk/gcbench/fragger/LinkedListFragger.java	Tue Nov 29 20:09:29 2016 +0100
+++ b/src/main/java/org/openjdk/gcbench/fragger/LinkedListFragger.java	Tue Nov 29 21:09:09 2016 +0100
@@ -1,5 +1,6 @@
 package org.openjdk.gcbench.fragger;
 
+import org.openjdk.gcbench.util.ratelimit.MultiTokenBucket;
 import org.openjdk.jmh.annotations.*;
 
 import java.util.LinkedList;
@@ -10,47 +11,43 @@
 @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
 @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
 @Fork(value = 1)
-@BenchmarkMode(Mode.AverageTime)
-@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
 @Threads(Threads.MAX)
 @State(Scope.Benchmark)
 public class LinkedListFragger {
 
-    @Param({"1", "10", "100", "1000", "10000"})
-    int size;
+    @Param({"1000"})
+    long ldsMB;
 
-    @Param({"1000"})
-    int ldsMB;
+    @Param({"10"})
+    int rate;
 
     List<Object> objects;
 
+    MultiTokenBucket bucket;
+
     int count;
 
+    private int getSizePerCount() {
+        return 24 + // Node
+               64; // payload
+    }
+
     @Setup
     public void setup() {
-        count = (int)Math.max(1, (1L * ldsMB * 1024 * 1024) / align(16 + 4 + size, 8));
-        objects = new LinkedList();
+        bucket = new MultiTokenBucket(rate);
+        count = (int)Math.max(1, ldsMB * 1024 * 1024 / getSizePerCount());
+        objects = new LinkedList<>();
         for (int c = 0; c < count; c++) {
-            objects.add(new byte[size]);
-        }
-    }
-
-    public static int align(int size, int align) {
-        if ((size % align) == 0) {
-            return size;
-        } else {
-            return ((size / align) + 1) * align;
+            objects.add(new byte[48]);
         }
     }
 
     @Benchmark
     public void test() {
-        doStore(ThreadLocalRandom.current().nextInt(count), new byte[size]);
-    }
-
-    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
-    private void doStore(int idx, byte[] obj) {
-        objects.set(idx, obj);
+        bucket.limit();
+        objects.set(ThreadLocalRandom.current().nextInt(count), new byte[48]);
     }
 
 }
--- a/src/main/java/org/openjdk/gcbench/fragger/TreeFragger.java	Tue Nov 29 20:09:29 2016 +0100
+++ b/src/main/java/org/openjdk/gcbench/fragger/TreeFragger.java	Tue Nov 29 21:09:09 2016 +0100
@@ -1,5 +1,6 @@
 package org.openjdk.gcbench.fragger;
 
+import org.openjdk.gcbench.util.ratelimit.MultiTokenBucket;
 import org.openjdk.jmh.annotations.*;
 
 import java.util.concurrent.ThreadLocalRandom;
@@ -8,42 +9,47 @@
 @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
 @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
 @Fork(1)
-@BenchmarkMode(Mode.AverageTime)
-@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
 @Threads(Threads.MAX)
 @State(Scope.Benchmark)
 public class TreeFragger {
 
-    @Param({"1", "10", "100", "1000", "10000"})
-    int size;
+    @Param({"1000"})
+    long ldsMB;
 
-    @Param({"1000"})
-    int ldsMB;
+    @Param({"10"})
+    int rate;
 
     Node root;
 
     int count;
 
+    MultiTokenBucket bucket;
+
+    private int getSizePerCount() {
+        return 24 + // Node
+               16; // payload
+    }
+
     @Setup
     public void setup() {
-        int sizePerCount =
-                        align(12 + 3*4, 8) +        // Node
-                        align(12 + 4 + size, 8); // array
-        count = (int)Math.max(1, (1L * ldsMB * 1024 * 1024) / sizePerCount);
+        bucket = new MultiTokenBucket(rate);
+        count = (int)Math.max(1, ldsMB * 1024 * 1024 / getSizePerCount());
 
-        root = new Node(new byte[size]);
+        root = new Node(new Object());
 
         for (int addr = 0; addr < count; addr++) {
             Node cur = root;
             for (int m = 31 - Integer.numberOfLeadingZeros(addr); m >= 0; m--) {
                 if ((addr & (1 << m)) != 0) {
                     if (cur.left == null) {
-                        cur.left = new Node(new byte[size]);
+                        cur.left = new Node(new Object());
                     }
                     cur = cur.left;
                 } else {
                     if (cur.right == null) {
-                        cur.right = new Node(new byte[size]);
+                        cur.right = new Node(new Object());
                     }
                     cur = cur.right;
                 }
@@ -61,11 +67,11 @@
 
     @Benchmark
     public void test() {
-        doStore(ThreadLocalRandom.current().nextInt(count), new byte[size]);
+        bucket.limit();
+        doStore(ThreadLocalRandom.current().nextInt(count), new Object());
     }
 
-    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
-    private void doStore(int addr, byte[] obj) {
+    private void doStore(int addr, Object obj) {
         Node cur = root;
         for (int m = 31 - Integer.numberOfLeadingZeros(addr); m >= 0; m--) {
             if ((addr & (1 << m)) != 0) {
--- a/src/main/java/org/openjdk/gcbench/tests/DimensionalTest.java	Tue Nov 29 20:09:29 2016 +0100
+++ b/src/main/java/org/openjdk/gcbench/tests/DimensionalTest.java	Tue Nov 29 21:09:09 2016 +0100
@@ -154,8 +154,14 @@
             );
         } catch (RunnerException e) {
             pw.print("FAILED: ");
-            for (Throwable t : e.getCause().getSuppressed()) {
-                pw.print(t.getMessage() + " ");
+            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();
         }