1 llvm-exegesis - LLVM Machine Instruction Benchmark
2 ==================================================
4 .. program:: llvm-exegesis
9 :program:`llvm-exegesis` [*options*]
14 :program:`llvm-exegesis` is a benchmarking tool that uses information available
15 in LLVM to measure host machine instruction characteristics like latency,
16 throughput, or port decomposition.
18 Given an LLVM opcode name and a benchmarking mode, :program:`llvm-exegesis`
19 generates a code snippet that makes execution as serial (resp. as parallel) as
20 possible so that we can measure the latency (resp. inverse throughput/uop decomposition)
22 The code snippet is jitted and, unless requested not to, executed on the
23 host subtarget. The time taken (resp. resource usage) is measured using
24 hardware performance counters. The result is printed out as YAML
25 to the standard output.
27 The main goal of this tool is to automatically (in)validate the LLVM's TableDef
28 scheduling models. To that end, we also provide analysis of the results.
30 :program:`llvm-exegesis` can also benchmark arbitrary user-provided code
36 :program:`llvm-exegesis` currently only supports X86 (64-bit only), ARM (AArch64
37 only), MIPS, and PowerPC (PowerPC64LE only) on Linux for benchmarking. Not all
38 benchmarking functionality is guaranteed to work on every platform.
39 :program:`llvm-exegesis` also has a separate analysis mode that is supported
40 on every platform on which LLVM is.
45 :program:`llvm-exegesis` supports benchmarking arbitrary snippets of assembly.
46 However, benchmarking these snippets often requires some setup so that they
47 can execute properly. :program:`llvm-exegesis` has two annotations and some
48 additional utilities to help with setup so that snippets can be benchmarked
51 * `LLVM-EXEGESIS-DEFREG <register name>` - Adding this annotation to the text
52 assembly snippet to be benchmarked marks the register as requiring a definition.
53 A value will automatically be provided unless a second parameter, a hex value,
54 is passed in. This is done with the `LLVM-EXEGESIS-DEFREG <register name> <hex value>`
55 format. `<hex value>` is a bit pattern used to fill the register. If it is a
56 value smaller than the register, it is sign extended to match the size of the
58 * `LLVM-EXEGESIS-LIVEIN <register name>` - This annotation allows specifying
59 registers that should keep their value upon starting the benchmark. Values
60 can be passed through registers from the benchmarking setup in some cases.
61 The registers and the values assigned to them that can be utilized in the
62 benchmarking script with a `LLVM-EXEGESIS-LIVEIN` are as follows:
64 * Scratch memory register - The specific register that this value is put in
65 is platform dependent (e.g., it is the RDI register on X86 Linux). Setting
66 this register as a live in ensures that a pointer to a block of memory (1MB)
67 is placed within this register that can be used by the snippet.
68 * `LLVM-EXEGESIS-MEM-DEF <value name> <size> <value>` - This annotation allows
69 specifying memory definitions that can later be mapped into the execution
70 process of a snippet with the `LLVM-EXEGESIS-MEM-MAP` annotation. Each
71 value is named using the `<value name>` argument so that it can be referenced
72 later within a map annotation. The size is specified in bytes the the value
73 is taken in hexadecimal. If the size of the value is less than the specified
74 size, the value will be repeated until it fills the entire section of memory.
75 Using this annotation requires using the subprocess execution mode.
76 * `LLVM-EXEGESIS-MEM-MAP <value name> <address>` - This annotation allows for
77 mapping previously defined memory definitions into the execution context of a
78 process. The value name refers to a previously defined memory definition and
79 the address is a decimal number that specifies the address the memory
80 definition should start at. Note that a single memory definition can be
81 mapped multiple times. Using this annotation requires the subprocess
84 EXAMPLE 1: benchmarking instructions
85 ------------------------------------
87 Assume you have an X86-64 machine. To measure the latency of a single
92 $ llvm-exegesis --mode=latency --opcode-name=ADD64rr
94 Measuring the uop decomposition or inverse throughput of an instruction works similarly:
98 $ llvm-exegesis --mode=uops --opcode-name=ADD64rr
99 $ llvm-exegesis --mode=inverse_throughput --opcode-name=ADD64rr
102 The output is a YAML document (the default is to write to stdout, but you can
103 redirect the output to a file using `--benchmarks-file`):
113 llvm_triple: x86_64-unknown-linux-gnu
114 num_repetitions: 10000
116 - { key: latency, value: 1.0058, debug_string: '' }
118 info: 'explicit self cycles, selecting one aliasing configuration.
124 To measure the latency of all instructions for the host architecture, run:
128 $ llvm-exegesis --mode=latency --opcode-index=-1
131 EXAMPLE 2: benchmarking a custom code snippet
132 ---------------------------------------------
134 To measure the latency/uops of a custom piece of code, you can specify the
135 `snippets-file` option (`-` reads from standard input).
139 $ echo "vzeroupper" | llvm-exegesis --mode=uops --snippets-file=-
141 Real-life code snippets typically depend on registers or memory.
142 :program:`llvm-exegesis` checks the liveliness of registers (i.e. any register
143 use has a corresponding def or is a "live in"). If your code depends on the
144 value of some registers, you need to use snippet annotations to ensure setup
145 is performed properly.
147 For example, the following code snippet depends on the values of XMM1 (which
148 will be set by the tool) and the memory buffer passed in RDI (live in).
152 # LLVM-EXEGESIS-LIVEIN RDI
153 # LLVM-EXEGESIS-DEFREG XMM1 42
154 vmulps (%rdi), %xmm1, %xmm2
155 vhaddps %xmm2, %xmm2, %xmm3
159 Example 3: benchmarking with memory annotations
160 -----------------------------------------------
162 Some snippets require memory setup in specific places to execute without
163 crashing. Setting up memory can be accomplished with the `LLVM-EXEGESIS-MEM-DEF`
164 and `LLVM-EXEGESIS-MEM-MAP` annotations. To execute the following snippet:
171 We need to have at least eight bytes of memory allocated starting `0x2000`.
172 We can create the necessary execution environment with the following
173 annotations added to the snippet:
177 # LLVM-EXEGESIS-MEM-DEF test1 4096 2147483647
178 # LLVM-EXEGESIS-MEM-MAP test1 8192
186 Assuming you have a set of benchmarked instructions (either latency or uops) as
187 YAML in file `/tmp/benchmarks.yaml`, you can analyze the results using the
192 $ llvm-exegesis --mode=analysis \
193 --benchmarks-file=/tmp/benchmarks.yaml \
194 --analysis-clusters-output-file=/tmp/clusters.csv \
195 --analysis-inconsistencies-output-file=/tmp/inconsistencies.html
197 This will group the instructions into clusters with the same performance
198 characteristics. The clusters will be written out to `/tmp/clusters.csv` in the
203 cluster_id,opcode_name,config,sched_class
205 2,ADD32ri8_DB,,WriteALU,1.00
206 2,ADD32ri_DB,,WriteALU,1.01
207 2,ADD32rr,,WriteALU,1.01
208 2,ADD32rr_DB,,WriteALU,1.00
209 2,ADD32rr_REV,,WriteALU,1.00
210 2,ADD64i32,,WriteALU,1.01
211 2,ADD64ri32,,WriteALU,1.01
212 2,MOVSX64rr32,,BSWAP32r_BSWAP64r_MOVSX64rr32,1.00
213 2,VPADDQYrr,,VPADDBYrr_VPADDDYrr_VPADDQYrr_VPADDWYrr_VPSUBBYrr_VPSUBDYrr_VPSUBQYrr_VPSUBWYrr,1.02
214 2,VPSUBQYrr,,VPADDBYrr_VPADDDYrr_VPADDQYrr_VPADDWYrr_VPSUBBYrr_VPSUBDYrr_VPSUBQYrr_VPSUBWYrr,1.01
215 2,ADD64ri8,,WriteALU,1.00
216 2,SETBr,,WriteSETCC,1.01
219 :program:`llvm-exegesis` will also analyze the clusters to point out
220 inconsistencies in the scheduling information. The output is an html file. For
221 example, `/tmp/inconsistencies.html` will contain messages like the following :
223 .. image:: llvm-exegesis-analysis.png
226 Note that the scheduling class names will be resolved only when
227 :program:`llvm-exegesis` is compiled in debug mode, else only the class id will
228 be shown. This does not invalidate any of the analysis results though.
235 Print a summary of command line options.
237 .. option:: --opcode-index=<LLVM opcode index>
239 Specify the opcode to measure, by index. Specifying `-1` will result
240 in measuring every existing opcode. See example 1 for details.
241 Either `opcode-index`, `opcode-name` or `snippets-file` must be set.
243 .. option:: --opcode-name=<opcode name 1>,<opcode name 2>,...
245 Specify the opcode to measure, by name. Several opcodes can be specified as
246 a comma-separated list. See example 1 for details.
247 Either `opcode-index`, `opcode-name` or `snippets-file` must be set.
249 .. option:: --snippets-file=<filename>
251 Specify the custom code snippet to measure. See example 2 for details.
252 Either `opcode-index`, `opcode-name` or `snippets-file` must be set.
254 .. option:: --mode=[latency|uops|inverse_throughput|analysis]
256 Specify the run mode. Note that some modes have additional requirements and options.
258 `latency` mode can be make use of either RDTSC or LBR.
259 `latency[LBR]` is only available on X86 (at least `Skylake`).
260 To run in `latency` mode, a positive value must be specified
261 for `x86-lbr-sample-period` and `--repetition-mode=loop`.
263 In `analysis` mode, you also need to specify at least one of the
264 `-analysis-clusters-output-file=` and `-analysis-inconsistencies-output-file=`.
266 .. option:: --benchmark-phase=[prepare-snippet|prepare-and-assemble-snippet|assemble-measured-code|measure]
268 By default, when `-mode=` is specified, the generated snippet will be executed
269 and measured, and that requires that we are running on the hardware for which
270 the snippet was generated, and that supports performance measurements.
271 However, it is possible to stop at some stage before measuring. Choices are:
272 * ``prepare-snippet``: Only generate the minimal instruction sequence.
273 * ``prepare-and-assemble-snippet``: Same as ``prepare-snippet``, but also dumps an excerpt of the sequence (hex encoded).
274 * ``assemble-measured-code``: Same as ``prepare-and-assemble-snippet``. but also creates the full sequence that can be dumped to a file using ``--dump-object-to-disk``.
275 * ``measure``: Same as ``assemble-measured-code``, but also runs the measurement.
277 .. option:: --x86-lbr-sample-period=<nBranches/sample>
279 Specify the LBR sampling period - how many branches before we take a sample.
280 When a positive value is specified for this option and when the mode is `latency`,
281 we will use LBRs for measuring.
282 On choosing the "right" sampling period, a small value is preferred, but throttling
283 could occur if the sampling is too frequent. A prime number should be used to
284 avoid consistently skipping certain blocks.
286 .. option:: --x86-disable-upper-sse-registers
288 Using the upper xmm registers (xmm8-xmm15) forces a longer instruction encoding
289 which may put greater pressure on the frontend fetch and decode stages,
290 potentially reducing the rate that instructions are dispatched to the backend,
291 particularly on older hardware. Comparing baseline results with this mode
292 enabled can help determine the effects of the frontend and can be used to
293 improve latency and throughput estimates.
295 .. option:: --repetition-mode=[duplicate|loop|min]
297 Specify the repetition mode. `duplicate` will create a large, straight line
298 basic block with `num-repetitions` instructions (repeating the snippet
299 `num-repetitions`/`snippet size` times). `loop` will, optionally, duplicate the
300 snippet until the loop body contains at least `loop-body-size` instructions,
301 and then wrap the result in a loop which will execute `num-repetitions`
302 instructions (thus, again, repeating the snippet
303 `num-repetitions`/`snippet size` times). The `loop` mode, especially with loop
304 unrolling tends to better hide the effects of the CPU frontend on architectures
305 that cache decoded instructions, but consumes a register for counting
306 iterations. If performing an analysis over many opcodes, it may be best to
307 instead use the `min` mode, which will run each other mode,
308 and produce the minimal measured result.
310 .. option:: --num-repetitions=<Number of repetitions>
312 Specify the target number of executed instructions. Note that the actual
313 repetition count of the snippet will be `num-repetitions`/`snippet size`.
314 Higher values lead to more accurate measurements but lengthen the benchmark.
316 .. option:: --loop-body-size=<Preferred loop body size>
318 Only effective for `-repetition-mode=[loop|min]`.
319 Instead of looping over the snippet directly, first duplicate it so that the
320 loop body contains at least this many instructions. This potentially results
321 in loop body being cached in the CPU Op Cache / Loop Cache, which allows to
322 which may have higher throughput than the CPU decoders.
324 .. option:: --max-configs-per-opcode=<value>
326 Specify the maximum configurations that can be generated for each opcode.
327 By default this is `1`, meaning that we assume that a single measurement is
328 enough to characterize an opcode. This might not be true of all instructions:
329 for example, the performance characteristics of the LEA instruction on X86
330 depends on the value of assigned registers and immediates. Setting a value of
331 `-max-configs-per-opcode` larger than `1` allows `llvm-exegesis` to explore
332 more configurations to discover if some register or immediate assignments
333 lead to different performance characteristics.
336 .. option:: --benchmarks-file=</path/to/file>
338 File to read (`analysis` mode) or write (`latency`/`uops`/`inverse_throughput`
339 modes) benchmark results. "-" uses stdin/stdout.
341 .. option:: --analysis-clusters-output-file=</path/to/file>
343 If provided, write the analysis clusters as CSV to this file. "-" prints to
344 stdout. By default, this analysis is not run.
346 .. option:: --analysis-inconsistencies-output-file=</path/to/file>
348 If non-empty, write inconsistencies found during analysis to this file. `-`
349 prints to stdout. By default, this analysis is not run.
351 .. option:: --analysis-filter=[all|reg-only|mem-only]
353 By default, all benchmark results are analysed, but sometimes it may be useful
354 to only look at those that to not involve memory, or vice versa. This option
355 allows to either keep all benchmarks, or filter out (ignore) either all the
356 ones that do involve memory (involve instructions that may read or write to
357 memory), or the opposite, to only keep such benchmarks.
359 .. option:: --analysis-clustering=[dbscan,naive]
361 Specify the clustering algorithm to use. By default DBSCAN will be used.
362 Naive clustering algorithm is better for doing further work on the
363 `-analysis-inconsistencies-output-file=` output, it will create one cluster
364 per opcode, and check that the cluster is stable (all points are neighbours).
366 .. option:: --analysis-numpoints=<dbscan numPoints parameter>
368 Specify the numPoints parameters to be used for DBSCAN clustering
369 (`analysis` mode, DBSCAN only).
371 .. option:: --analysis-clustering-epsilon=<dbscan epsilon parameter>
373 Specify the epsilon parameter used for clustering of benchmark points
376 .. option:: --analysis-inconsistency-epsilon=<epsilon>
378 Specify the epsilon parameter used for detection of when the cluster
379 is different from the LLVM schedule profile values (`analysis` mode).
381 .. option:: --analysis-display-unstable-clusters
383 If there is more than one benchmark for an opcode, said benchmarks may end up
384 not being clustered into the same cluster if the measured performance
385 characteristics are different. by default all such opcodes are filtered out.
386 This flag will instead show only such unstable opcodes.
388 .. option:: --ignore-invalid-sched-class=false
390 If set, ignore instructions that do not have a sched class (class idx = 0).
392 .. option:: --mtriple=<triple name>
394 Target triple. See `-version` for available targets.
396 .. option:: --mcpu=<cpu name>
398 If set, measure the cpu characteristics using the counters for this CPU. This
399 is useful when creating new sched models (the host CPU is unknown to LLVM).
400 (`-mcpu=help` for details)
402 .. option:: --analysis-override-benchmark-triple-and-cpu
404 By default, llvm-exegesis will analyze the benchmarks for the triple/CPU they
405 were measured for, but if you want to analyze them for some other combination
406 (specified via `-mtriple`/`-mcpu`), you can pass this flag.
408 .. option:: --dump-object-to-disk=true
410 If set, llvm-exegesis will dump the generated code to a temporary file to
411 enable code inspection. Disabled by default.
413 .. option:: --use-dummy-perf-counters
415 If set, llvm-exegesis will not read any real performance counters and
416 return a dummy value instead. This can be used to ensure a snippet doesn't
417 crash when hardware performance counters are unavailable and for
418 debugging :program:`llvm-exegesis` itself.
420 .. option:: --execution-mode=[inprocess,subprocess]
422 This option specifies what execution mode to use. The `inprocess` execution
423 mode is the default. The `subprocess` execution mode allows for additional
424 features such as memory annotations but is currently restricted to X86-64
430 :program:`llvm-exegesis` returns 0 on success. Otherwise, an error message is
431 printed to standard error, and the tool returns a non 0 value.