Commit Graph
3 Commits
Author SHA1 Message Date
Chandler CarruthandRichard Smith 3e7b8ade82 Restructure benchmark for stability. (#3141)
It was pointed out in review that the approach to building random inputs
for the benchmark would produce significantly varying input lengths and
cause unavoidable noise of as much as 3% between runs.

While initially, these were only used for very coarse measurements, this
is a definite problem, and so this PR restructures things along the
lines suggested. Rather than generating random lengths or random
selections according to distributions, instead the lengths and coverage
of sets are done deterministically. Then the sequences are randomized in
order to prevent getting stuck in a silent local minima or maxima.

The technique works to ensure that the randomness is done on every run
of the benchmark, not just every run of the program, so that we don't
have noise hidden from run-to-run. That means fresh memory allocation
and some wasted time computed freshly shuffled inputs, but makes sure
the unavoidable noise from things like ASLR show up (as much as
possible) even with simple repetitions of the benchmark runs.

As part of this, this PR moves towards building an entirely custom
distribution of identifier lengths based on the direct measurements of
the LLVM codebase. These measurements are provided by a script that will
be in a subsequent PR, but the exact distribution doesn't matter as much
as our ability to control it and build on it in a fully deterministic
way.

To help with analyzing all of these, we also start tracking the bytes
processed in addition to the tokens processed as rates. The naming is
changed to be similar, and this produces the following nice output from
the benchmark now:
```
---------------------------------------------------------------------------------------------------------------
Benchmark                                  Time             CPU   Iterations bytes_per_second tokens_per_second
---------------------------------------------------------------------------------------------------------------
BM_ValidKeywords                     3365571 ns      3365577 ns          206       177.449M/s        29.7126M/s
BM_ValidIdentifiers<1, 64, false>   12646151 ns     12645834 ns           52       116.466M/s        7.90774M/s
BM_ValidIdentifiers<1, 1, true>      4388390 ns      4388141 ns          161       65.1988M/s        22.7887M/s
BM_ValidIdentifiers<3, 5, true>     16286551 ns     16286572 ns           43       35.1334M/s        6.14003M/s
BM_ValidIdentifiers<3, 16, true>    15798770 ns     15797567 ns           44       69.4229M/s        6.33009M/s
BM_ValidIdentifiers<12, 64, true>   15670499 ns     15670257 ns           38       243.421M/s        6.38152M/s
BM_ValidMix/10/40                    7415940 ns      7415564 ns           94       134.257M/s        13.4852M/s
BM_ValidMix/25/30                    7349454 ns      7349402 ns           95       121.762M/s        13.6065M/s
BM_ValidMix/50/20                    6691223 ns      6690969 ns          105         100.3M/s        14.9455M/s
BM_ValidMix/75/10                    5131517 ns      5131263 ns          135       86.4556M/s        19.4884M/s
```

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2023-08-24 19:45:05 +00:00
Chandler Carruth 5cb7be2794 Expand lexing benchmarks a little bit. (#3123)
This adds a benchmark that tries to synthesize mixtures of symbols,
keywords, and identifiers. It tweaks the distribution of identifier
lengths based on some empirical measurements of, for example LLVM's
codebase.

Also establish a framework for skewing the symbol distribution, although
that one is based entirely on intuition and not measurements. It should
be adjusted as we have measurements.

The ratios between symbols, keywords, and identifiers is also
unmeasured, but several different ratios are covered.

Neither literals nor grouping symbols are included yet, as both present
some additional challenges in forming them, and this seemed like
a plausible increment in expanding the benchmark coverage.
2023-08-23 17:12:27 +00:00
5c2338dbd0 Introduce a full lexer benchmark. (#3121)
Currently this is focused on benchmarking the identifier and token
lexing paths, but should expand in the future to cover other parts of
the lexer.

In order to effectively benchmark tokens, this adds support to the
`token_kind` library to produce a list of all the tokens in Carbon that
the benchmark can use to create random inputs.

For identifiers, the benchmark has support for benchmarking different
distributions of identifier sizes so it is easy to zoom into the
performance specifically of short or long identifiers.

This benchmarking is motivated by profiling overall toolchain
performance and noticing that an unreasonable amount of time is spent in
the lexer. In turn, the identifier lexing was surprisingly hot. I have
performance improvements in the works following this, but wanted to
separately introduce the benchmarking framework as the review focus will
be completely different.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-08-22 22:55:06 +00:00