@@ -15,8 +15,8 @@ Please make sure your dev machine satisfies those prerequisites.
15
15
16
16
### Before you continue
17
17
18
- The minimal supported Rust version for MMTk-OpenJDK binding is 1.57 .0. Make sure your Rust version is higher than this. We test MMTk-OpenJDK
19
- binding with Rust 1.59.0 (as specified in [ ` rust-toolchain ` ] ( mmtk/rust-toolchain ) ).
18
+ The minimal supported Rust version for MMTk-OpenJDK binding is 1.61 .0. Make sure your Rust version is higher than this. We test MMTk-OpenJDK
19
+ binding with Rust 1.66.1 (as specified in [ ` rust-toolchain ` ] ( mmtk/rust-toolchain ) ).
20
20
You may also need to use ssh-agent to authenticate with github (see [ here] ( https://github.com/rust-lang/cargo/issues/3487 ) for more info):
21
21
22
22
``` console
@@ -126,6 +126,67 @@ $ make CONF=linux-x86_64-normal-server-release THIRD_PARTY_HEAP=$PWD/../mmtk-ope
126
126
127
127
The output jdk is then found at ` ./build/linux-x86_64-normal-server-release/images/jdk ` .
128
128
129
+ ### Profile-Guided Optimized Build
130
+
131
+ In order to get the best performance, we recommend using a profile-guided
132
+ optimized (PGO) build. Rust supports [ PGO
133
+ builds] ( https://doc.rust-lang.org/rustc/profile-guided-optimization.html ) by
134
+ directly hooking into the LLVM profiling infrastructure. In order to have the
135
+ correct LLVM tools version, you should install the relevant ` llvm-tools-preview `
136
+ component using ` rustup ` :
137
+
138
+ ``` console
139
+ $ rustup component add llvm-tools-preview
140
+ ```
141
+
142
+ In this example, we focus on the DaCapo benchmarks and the ` GenImmix `
143
+ collector. For best results, it is recommended to profile the workload you are
144
+ interested in measuring. We use ` fop ` as it is a relatively small benchmark but
145
+ also exercises the GC. In order to best tune our GC performance, we use a
146
+ stress factor of 4 MB in order to trigger more GC events.
147
+
148
+ First we compile MMTk with profiling support:
149
+
150
+ ``` console
151
+ $ RUSTFLAGS=" -Cprofile-generate=/tmp/$USER /pgo-data" make CONF=linux-x86_64-normal-server-release THIRD_PARTY_HEAP=$PWD /../mmtk-openjdk/openjdk images
152
+ $ rm -rf /tmp/$USER /pgo-data/*
153
+ ```
154
+ We clear the ` /tmp/$USER/pgo-data ` directory as during compilation, the JVM we
155
+ have created is used in a bootstrap process, resulting in profile data being
156
+ emitted.
157
+
158
+ We then run ` fop ` in order to get some profiling data. Note that your location
159
+ for the DaCapo benchmarks may be different:
160
+
161
+ ``` bash
162
+ MMTK_PLAN=GenImmix MMTK_STRESS_FACTOR=4194304 MMTK_PRECISE_STRESS=false ./build/linux-x86_64-normal-server-release/images/jdk/bin/java -XX:MetaspaceSize=500M -XX:+DisableExplicitGC -XX:-TieredCompilation -Xcomp -XX:+UseThirdPartyHeap -Xms60M -Xmx60M -jar /usr/share/benchmarks/dacapo/dacapo-evaluation-git-6e411f33.jar -n 5 fop
163
+ ```
164
+
165
+ We have to merge the profiling data into something we can feed into the Rust
166
+ compiler using ` llvm-profdata ` :
167
+
168
+ ``` console
169
+ $ /opt/rust/toolchains/1.66.1-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-profdata merge -o /tmp/$USER /pgo-data/merged.profdata /tmp/$USER /pgo-data
170
+ ```
171
+
172
+ The location of your version of ` llvm-profdata ` may be different to what we
173
+ have above. * Make sure to only use a version of ` llvm-profdata ` that matches
174
+ your Rust version.*
175
+
176
+ Finally, we build a new image using the profiling data as an input:
177
+
178
+ ``` console
179
+ $ RUSTFLAGS=" -Cprofile-use=/tmp/$USER /pgo-data/merged.profdata -Cllvm-args=-pgo-warn-missing-function" make CONF=linux-x86_64-normal-server-release THIRD_PARTY_HEAP=$PWD /../mmtk-openjdk/openjdk images
180
+ ```
181
+
182
+ We now have an OpenJDK build under
183
+ ` ./build/linux-x86_64-normal-server-release/images/jdk ` with MMTk that has been
184
+ optimized using PGO.
185
+
186
+ For ease of use, we have provided an example script which does the above in
187
+ ` .github/scripts/pgo-build.sh ` that you may adapt for your purposes. Note that
188
+ you may have to change the location of ` llvm-profdata ` .
189
+
129
190
### Location of Mark-bit
130
191
The location of the mark-bit can be specified by the environment variable
131
192
` MARK_IN_HEADER ` . By default, the mark-bit is located on the side (in a side
0 commit comments