changeset 23:f2161828d5d4

Blackhole.consumeCPU refresh, added sample.
author shade
date Fri, 10 May 2013 23:45:01 +0400
parents 36b3f91f5cf5
children af468ba6bc2e
files jmh-core/src/main/java/org/openjdk/jmh/logic/BlackHole.java jmh-samples/src/main/java/org/openjdk/jmh/samples/JMHSample_21_ConsumeCPU.java
diffstat 2 files changed, 127 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/jmh-core/src/main/java/org/openjdk/jmh/logic/BlackHole.java	Fri May 10 23:33:23 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/logic/BlackHole.java	Fri May 10 23:45:01 2013 +0400
@@ -329,21 +329,19 @@
         }
     }
 
-    public static long consumedCPU;
+    public static volatile long consumedCPU = 42;
 
     /**
      * Consume some amount of time tokens.
-     * This call does the CPU work linear to the number of tokens.
-     * <p>
-     * One token is really small, around 40 clocks on 2.0 Ghz i5.
-     * The method is also having static overhead of around 20ns per call.
+     * This method does the CPU work almost linear to the number of tokens.
+     * One token is really small, around 3 clocks on 2.0 Ghz i5,
+     * see JMH samples for the complete demo.
      *
      * @param tokens CPU tokens to consume
      */
     public static void consumeCPU(long tokens) {
         // randomize start so that JIT could not memoize;
-        // this costs significantly on low token count.
-        long t = System.nanoTime();
+        long t = consumedCPU;
 
         for (long i = 0; i < tokens; i++) {
             t += (t * 0x5DEECE66DL + 0xBL) & (0xFFFFFFFFFFFFL);
@@ -351,7 +349,8 @@
 
         // need to guarantee side-effect on the result,
         // but can't afford contention; make sure we update the shared state
-        // only in the unlikely even
+        // only in the unlikely case, so not to do the furious writes,
+        // but still dodge DCE.
         if (t == 42) {
             consumedCPU += t;
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-samples/src/main/java/org/openjdk/jmh/samples/JMHSample_21_ConsumeCPU.java	Fri May 10 23:45:01 2013 +0400
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.samples;
+
+import org.openjdk.jmh.annotations.BenchmarkType;
+import org.openjdk.jmh.annotations.GenerateMicroBenchmark;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.logic.BlackHole;
+
+import java.util.concurrent.TimeUnit;
+
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class JMHSample_21_ConsumeCPU {
+
+    /*
+     * At times you require the test to burn some of the cycles doing nothing.
+     * In many cases, you *do* want to burn the cycles instead of waiting.
+     *
+     * For these occasions, we have the infrastructure support. Blackholes
+     * can not only consume the values, but also the time! Run this test
+     * to get familiar with this part of JMH.
+     *
+     * (Note we use static method because most of the use cases are deep
+     * within the testing code, and propagating blackholes is tedious).
+     */
+
+    @GenerateMicroBenchmark(BenchmarkType.AverageTimePerOp)
+    public void consume_0000() {
+        BlackHole.consumeCPU(0);
+    }
+
+    @GenerateMicroBenchmark(BenchmarkType.AverageTimePerOp)
+    public void consume_0001() {
+        BlackHole.consumeCPU(1);
+    }
+
+    @GenerateMicroBenchmark(BenchmarkType.AverageTimePerOp)
+    public void consume_0002() {
+        BlackHole.consumeCPU(2);
+    }
+
+    @GenerateMicroBenchmark(BenchmarkType.AverageTimePerOp)
+    public void consume_0004() {
+        BlackHole.consumeCPU(4);
+    }
+
+    @GenerateMicroBenchmark(BenchmarkType.AverageTimePerOp)
+    public void consume_0008() {
+        BlackHole.consumeCPU(8);
+    }
+
+    @GenerateMicroBenchmark(BenchmarkType.AverageTimePerOp)
+    public void consume_0016() {
+        BlackHole.consumeCPU(16);
+    }
+
+    @GenerateMicroBenchmark(BenchmarkType.AverageTimePerOp)
+    public void consume_0032() {
+        BlackHole.consumeCPU(32);
+    }
+
+    @GenerateMicroBenchmark(BenchmarkType.AverageTimePerOp)
+    public void consume_0064() {
+        BlackHole.consumeCPU(64);
+    }
+
+    @GenerateMicroBenchmark(BenchmarkType.AverageTimePerOp)
+    public void consume_0128() {
+        BlackHole.consumeCPU(128);
+    }
+
+    @GenerateMicroBenchmark(BenchmarkType.AverageTimePerOp)
+    public void consume_0256() {
+        BlackHole.consumeCPU(256);
+    }
+
+    @GenerateMicroBenchmark(BenchmarkType.AverageTimePerOp)
+    public void consume_0512() {
+        BlackHole.consumeCPU(512);
+    }
+
+    @GenerateMicroBenchmark(BenchmarkType.AverageTimePerOp)
+    public void consume_1024() {
+        BlackHole.consumeCPU(1024);
+    }
+
+    /*
+     * HOW TO RUN THIS TEST:
+     *
+     * You can run this test with:
+     *    $ mvn clean install
+     *    $ java -jar target/microbenchmarks.jar ".*JMHSample_21.*" -w 1 -r 1 -i 5
+     *
+     * Note the single token is just a few cycles, and the more tokens
+     * you request, then more work is spent (almost linerarly)
+     */
+
+}