Need some help for a book intro to JMH
Dr Heinz M. Kabutz
heinz at javaspecialists.eu
Fri Aug 12 21:13:47 UTC 2016
Hi Bruce,
it is "by design"...
I've logged a bug, but I doubt that it will ever be fixed:
https://bugs.openjdk.java.net/browse/JDK-8161676
Whether you have a single core or dual core (meaning
Runtime.getRuntime().availableProcessors() returns 1 or 2), the
parallelism in the common FJP is reported as 1 (number of hardware
threads - 1). So the parallel algorithms in Arrays all just throw up
their hands and do it sequentially. Note that it looks at the number of
hardware threads, rather than cores.
Regards
Heinz
--
Dr Heinz M. Kabutz (PhD CompSci)
Author of "The Java(tm) Specialists' Newsletter"
Sun/Oracle Java Champion since 2005
JavaOne Rock Star Speaker 2012
http://www.javaspecialists.eu
Tel: +30 69 75 595 262
Skype: kabutz
Bruce Eckel wrote:
> I'm using JMH in parts of an upcoming Java book. I've got some other parts
> working but have gotten stuck on the introduction because JMH is producing
> rather unexpected results.
>
> I'm using Arrays.setAll() vs Arrays.parallelSetAll() here because I've
> already shown the perils of trying to write your own benchmarking system
> using that example and it has demonstrated it well (I can include the whole
> section if you want but I wanted to start by focusing on the JMH part).
>
> To reproduce it:
> git clone https://github.com/BruceEckel/OnJava8-Examples
> cd OnJava8-Examples
> gradlew :verifying:jmh
>
> So my questions are:
> 1. Is Arrays.setAll() vs Arrays.parallelSetAll() just too tricky and subtle
> as an example, or are there JMH annotations I can add to fix this?
> 2. Is there a better introductory example I should be using? (Ideally such
> an example would also show problems when using simple timing).
>
> Here is the introductory section (so far), including test results:
>
> ### Introducing JMH
>
> At this writing, the only microbenchmark system for Java that produced
> decent
> results is The *Java Microbenchmarking Harness*
> [JMH](http://openjdk.java.net/projects/code-tools/jmh/). Configuring and
> using
> JMH by hand is tricky, but fortunately the book's `build.gradle` automates
> everything so you don't need to struggle with it.
>
> It's possible to write JMH code so it can be run from the command line, but
> the
> recommended approach is to let the JMH system run the tests for you. JMH
> attempts to make the writing of benchmarks as easy as possible. For
> example, we
> can rewrite `BadMicroBenchmark.java` to use JMH:
>
> ```java
> // verifying/jmhtests/ParallelSetAll.java
> package verifying.jmhtests;
> import java.util.*;
> import org.openjdk.jmh.annotations.*;
>
> @State(Scope.Thread)
> public class ParallelSetAll {
> private long[] la;
> @Setup
> public void setup() {
> la = new long[20_000_000];
> }
> @Benchmark
> public void setAll() {
> Arrays.setAll(la, n -> n);
> }
> @Benchmark
> public void parallelSetAll() {
> Arrays.parallelSetAll(la, n -> n);
> }
> }
> ```
>
> To run the benchmark, you use an explicit command (executed from the root
> directory of the example code), so the benchmarking doesn't happen as part
> of
> the normal `gradlew run` command:
>
> ```
> gradlew :verifying:jmh
> ```
>
> You'll see that it takes a *long* time, around 15 minutes depending on your
> machine. Each test has a default of 20 warmup iterations, and 20 test
> iterations. The output indicates where the results are summarized in a
> `results.txt` file. This is from my 2-core laptop running Windows 10:
>
> ```
> Benchmark Mode Cnt Score Error Units
> ParallelSetAll.parallelSetAll thrpt 200 33.496 ± 0.125 ops/s
> ParallelSetAll.setAll thrpt 200 32.936 ± 1.254 ops/s
> ```
>
> On my 4-core laptop running Windows 10, the results are different:
>
> ```
> Benchmark Mode Cnt Score Error Units
> ParallelSetAll.parallelSetAll thrpt 200 19.621 ± 0.254 ops/s
> ParallelSetAll.setAll thrpt 200 30.875 ± 0.038 ops/s
> ```
>
> Here are the results from the same laptop, running Linux Mint:
>
> ```
> Benchmark Mode Cnt Score Error Units
> ParallelSetAll.parallelSetAll thrpt 200 31.335 ± 0.023 ops/s
> ParallelSetAll.setAll thrpt 200 34.842 ± 0.066 ops/s
> ```
>
> On the Appveyor *Continuous Integration* (CI) server, which provides two
> dedicated cores, the results are:
>
> ```
> Benchmark Mode Cnt Score Error Units
> ParallelSetAll.parallelSetAll thrpt 200 98.987 ± 0.644 ops/s
> ParallelSetAll.setAll thrpt 200 53.148 ± 0.165 ops/s
> ```
>
> On Travis-ci, which provides two "bursted" cores, the results are:
>
> ```
> Benchmark Mode Cnt Score Error Units
> ParallelSetAll.parallelSetAll thrpt 200 63.895 ± 6.768 ops/s
> ParallelSetAll.setAll thrpt 200 54.631 ± 0.298 ops/s
> ```
>
>
>
> -- Bruce Eckel
> www.MindviewInc.com <http://www.mindviewinc.com/>
> Blog: BruceEckel.github.io
> www.WinterTechForum.com
> www.AtomicScala.com
> www.Reinventing-Business.com
> http://www.TrustOrganizations.com <http://www.ScalaSummit.com>
>
>
More information about the jmh-dev
mailing list