Skip to content

Documentation and automation for using JITWatch to analyse JMH benchmarks #7294

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 23, 2018

Conversation

retronym
Copy link
Member

@retronym retronym commented Oct 1, 2018

I found JITWatch really useful to drill into regressions in HashMap performance recently, but its a pain to configure manually.

This PR automates the generation of a config file containing the sources (including source JARs of dependencies) and classes (including dependency JARs).

Instructions

(These are also in the benchmark README.md)

You can generate the hotspot.log file for a benchmark run by adding the required JVM options
to JMH benchmark execution:

sbt:root> bench/jmh:run scala.collection.mutable.ArrayOpsBenchmark.insertInteger -psize=1000 -f1 -jvmArgs -XX:+UnlockDiagnosticVMOptions -jvmArgs -XX:+TraceClassLoading -jvmArgs -XX:+LogCompilation -jvmArgs -XX:LogFile=hotspot.log -jvmArgs -XX:+PrintAssembly
...
[info] Loaded disassembler from /Users/jz/.jabba/jdk/1.8.172/Contents/Home/jre/lib/hsdis-amd64.dylib
[info] Decoding compiled method 0x0000000113f60bd0:
[info] Code:
[info] [Disassembling for mach='i386:x86-64']
[info] [Entry Point]
[info] [Constants]
[info]   # {method} {0x000000010ffa0000} 'hashCode' '()I' in 'java/lang/String'
[info]   #           [sp+0x40]  (sp of caller)
[info]   0x0000000113f60d40: mov    r10d,DWORD PTR [rsi+0x8]
[info]   0x0000000113f60d44: shl    r10,0x3
...
[info] # Run complete. Total time: 00:00:30
[info] Benchmark                        (size)  Mode  Cnt       Score      Error  Units
[info] ArrayOpsBenchmark.insertInteger    1000  avgt   10  188199.582 ± 5930.520  ns/op

JITWatch requires configuration of the class and source path. We can generate that with a custom
task in our build:

sbt> bench/jmh:jitwatchConfigFile
[info] Resolving jline#jline;2.14.6 ...
jmh
[info] ./launchUI.sh -Djitwatch.config.file=/Users/jz/code/scala/test/benchmarks/target/jitwatch-jmh.properties

sbt> ^C

Build jitwatch.

$ git clone https://github.com/AdoptOpenJDK/jitwatch
$ cd jitwatch
$ mvn install

Launch with the generated config file.

$ ./launchUI.sh -Djitwatch.config.file=/Users/jz/code/scala/test/benchmarks/target/jitwatch-jmh.properties

image

image

image

@scala-jenkins scala-jenkins added this to the 2.13.0-RC1 milestone Oct 1, 2018
@retronym retronym requested a review from szeiger October 1, 2018 05:20
@retronym
Copy link
Member Author

retronym commented Oct 1, 2018

The best way to review/improve the PR would be to try to follow the instructions and see how far you get :)

Copy link
Member

@lrytz lrytz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really great! In other words, please share more of the tricks in your wizardry toolbox 😃

I'll give it a try. The test failure would go away after a rebase (#7289 (comment)).

@@ -72,13 +72,74 @@ For an Oracle (or other compatible) JVM not set up by your distribution,
you may also need to copy or link the disassembler library
to the `jre/lib/`_`architecture`_ directory inside your JVM installation directory.

The JITWatch project has [hsdis build instructions](https://github.com/AdoptOpenJDK/jitwatch/wiki/Building-hsdis).
One way to obtain HSDIS is to use [the binaries](https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/hsdis/intel/) which are used ing the [Graal build](https://github.com/oracle/graal/blob/master/compiler/mx.compiler/mx_graal_tools.py#L94-L119).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo "ing"

@smarter
Copy link
Member

smarter commented Oct 1, 2018

Very neat, can we expect an sbt-jitwatch ? :)

@retronym
Copy link
Member Author

retronym commented Oct 1, 2018

Very neat, can we expect an sbt-jitwatch

I'll push this up to sbt-jmh once it stabilizes a bit.

Copy link
Member

@lrytz lrytz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worked for me! 👍

@@ -72,13 +72,74 @@ For an Oracle (or other compatible) JVM not set up by your distribution,
you may also need to copy or link the disassembler library
to the `jre/lib/`_`architecture`_ directory inside your JVM installation directory.

The JITWatch project has [hsdis build instructions](https://github.com/AdoptOpenJDK/jitwatch/wiki/Building-hsdis).
One way to obtain HSDIS is to use [the binaries](https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/hsdis/intel/) which are used in the [Graal build](https://github.com/oracle/graal/blob/master/compiler/mx.compiler/mx_graal_tools.py#L94-L119).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For macOS there are currently two files there: hsdis-amd64-darwin-67f6d23cbebd8998450a88b5bef362171f66f11a.dylib and hsdis-amd64-darwin-fdb13ef0d7d23d93dacaae9c98837bea0d4fc5a2.dylib. I usesd the fdb13... version, which seems to work, didn't try the other. Also I had to rename it to hsdis-amd64.dylib to make it work (and put it int the jre/lib/server directory).

task in our build:

```
sbt> bench/jmh:jitwatchConfigFile
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sbt logs an error for me

sbt:root> bench/jmh:jitwatchConfigFile
[error] 	local: bad info.apiURL found in /Users/luc/.ivy2/local/org.scala-lang/scala-reflect/2.13.0-pre-SNAPSHOT/ivys/ivy.xml: expected='http://www.scala-lang.org/api/2.13.0-pre-SNAPSHOT/' found='null'

and then

[warn] 	::::::::::::::::::::::::::::::::::::::::::::::
[warn] 	::          UNRESOLVED DEPENDENCIES         ::
[warn] 	::::::::::::::::::::::::::::::::::::::::::::::
[warn] 	:: org.scala-lang#scala-reflect;2.13.0-pre-SNAPSHOT: java.text.ParseException: inconsistent module descriptor file found in '/Users/luc/.ivy2/local/org.scala-lang/scala-reflect/2.13.0-pre-SNAPSHOT/ivys/ivy.xml': bad info.apiURL found in /Users/luc/.ivy2/local/org.scala-lang/scala-reflect/2.13.0-pre-SNAPSHOT/ivys/ivy.xml: expected='http://www.scala-lang.org/api/2.13.0-pre-SNAPSHOT/' found='null';
[warn] 	::::::::::::::::::::::::::::::::::::::::::::::

but the generated file works nevertheless.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how to get rid of that.

@retronym retronym merged commit be29631 into scala:2.13.x Oct 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants