-
Notifications
You must be signed in to change notification settings - Fork 29
Separate harness implementation from the harness framework #446
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
Open
rafaelfranca
wants to merge
6
commits into
main
Choose a base branch
from
rmf-better-harness
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
eb606d6
Movel all hardness to a single directory
rafaelfranca 4c84b90
Keep the harness implementation separated from the harness framework
rafaelfranca b4a090e
Improve the run_once script to better handle Ruby options and harness…
rafaelfranca 66c2e95
Allow using HARNESS environment variable to select harness
rafaelfranca 2de2fee
Improve chain harness documentation and error handling
rafaelfranca 01698a8
Build harness arguments once during initialization
rafaelfranca File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -6,7 +6,7 @@ Small set of benchmarks and scripts for the Ruby programming language. | |||||
| The benchmarks are found in the `benchmarks` directory. Individual Ruby files | ||||||
| in `benchmarks` are microbenchmarks. Subdirectories under `benchmarks` are | ||||||
| larger macrobenchmarks. Each benchmark relies on a harness found in | ||||||
| [./harness/harness.rb](harness/harness.rb). The harness controls the number of times a benchmark is | ||||||
| [./harness/default.rb](harness/default.rb). The harness controls the number of times a benchmark is | ||||||
| run, and writes timing values into an output file. | ||||||
|
|
||||||
| The `run_benchmarks.rb` script (optional) traverses the `benchmarks` directory and | ||||||
|
|
@@ -97,8 +97,8 @@ This is the easiest way to run a single benchmark. | |||||
| It requires no setup at all and assumes nothing about the Ruby you are benchmarking. | ||||||
| It's also convenient for profiling, debugging, etc, especially since all benchmarked code runs in that process. | ||||||
|
|
||||||
| ``` | ||||||
| ruby benchmarks/some_benchmark.rb | ||||||
| ```bash | ||||||
| ruby benchmarks/fib.rb | ||||||
| ``` | ||||||
|
|
||||||
| ### Benchmark organization | ||||||
|
|
@@ -138,19 +138,19 @@ There are two Ractor-related categories: | |||||
|
|
||||||
| * **`--category ractor`** - Runs both regular benchmarks marked with `ractor: | ||||||
| true` in `benchmarks.yml` AND all benchmarks from the `benchmarks-ractor` | ||||||
| directory. The `harness-ractor` harness is used for both types of benchmark. | ||||||
| directory. The `ractor` harness is used for both types of benchmark. | ||||||
|
|
||||||
| * **`--category ractor-only`** - Runs ONLY benchmarks from the | ||||||
| `benchmarks-ractor` directory, ignoring regular benchmarks even if they are | ||||||
| marked with `ractor: true`. This category also automatically uses the | ||||||
| `harness-ractor` harness. | ||||||
| `ractor` harness. | ||||||
|
|
||||||
| ### Directory Structure | ||||||
|
|
||||||
| The `benchmarks-ractor/` directory sits at the same level as the main | ||||||
| `benchmarks` directory, and contains Ractor-specific benchmark | ||||||
| implementations that are designed to test Ractor functionality. They are not | ||||||
| intended to be used with any harness except `harness-ractor`. | ||||||
| intended to be used with any harness except `ractor`. | ||||||
|
|
||||||
| ### Usage Examples | ||||||
|
|
||||||
|
|
@@ -162,7 +162,7 @@ intended to be used with any harness except `harness-ractor`. | |||||
| ./run_benchmarks.rb --category ractor-only | ||||||
| ``` | ||||||
|
|
||||||
| Note: The `harness-ractor` harness is automatically selected when using these | ||||||
| Note: The `ractor` harness is automatically selected when using these | ||||||
| categories, so there's no need to specify `--harness` manually. | ||||||
|
|
||||||
| ## Ruby options | ||||||
|
|
@@ -211,26 +211,74 @@ This file will then be passed to the underlying Ruby interpreter with | |||||
|
|
||||||
| ## Harnesses | ||||||
|
|
||||||
| You can find several test harnesses in this repository: | ||||||
| You can find several test harnesses in the `harness/` directory: | ||||||
|
|
||||||
| * `default` - the normal default harness, with duration controlled by warmup iterations and time/count limits | ||||||
| * `bips` - a harness that measures iterations/second until stable | ||||||
| * `continuous` - a harness that adjusts the batch sizes of iterations to run in stable iteration size batches | ||||||
| * `once` - a simplified harness that simply runs once | ||||||
| * `perf` - a simplified harness that runs for exactly the hinted number of iterations | ||||||
| * `stackprof` - a harness to profile the benchmark with stackprof | ||||||
| * `stats` - count method calls and loop iterations | ||||||
| * `vernier` - a harness to profile the benchmark with vernier | ||||||
| * `warmup` - a harness which runs as long as needed to find warmed up (peak) performance | ||||||
| * `chain` - a harness to chain multiple harnesses together | ||||||
| * `mplr` - a harness for multiple iterations with time limits | ||||||
|
|
||||||
| ### Selecting a harness | ||||||
|
|
||||||
| **Using the `HARNESS` environment variable** | ||||||
|
|
||||||
| ```bash | ||||||
| # Run with specific harness | ||||||
| HARNESS=perf ruby benchmarks/fib.rb | ||||||
| HARNESS=stackprof ruby benchmarks/railsbench/benchmark.rb | ||||||
| HARNESS=vernier ruby benchmarks/optcarrot/benchmark.rb | ||||||
|
|
||||||
| # Combine with Ruby options | ||||||
| HARNESS=perf ruby --yjit benchmarks/fib.rb | ||||||
| HARNESS=once ruby --yjit-stats benchmarks/railsbench/benchmark.rb | ||||||
| ``` | ||||||
|
|
||||||
| * harness - the normal default harness, with duration controlled by warmup iterations and time/count limits | ||||||
| * harness-bips - a harness that measures iterations/second until stable | ||||||
| * harness-continuous - a harness that adjusts the batch sizes of iterations to run in stable iteration size batches | ||||||
| * harness-once - a simplified harness that simply runs once | ||||||
| * harness-perf - a simplified harness that runs for exactly the hinted number of iterations | ||||||
| * harness-stackprof - a harness to profile the benchmark with stackprof | ||||||
| * harness-stats - count method calls and loop iterations | ||||||
| * harness-vernier - a harness to profile the benchmark with vernier | ||||||
| * harness-warmup - a harness which runs as long as needed to find warmed up (peak) performance | ||||||
| **Alternative: Use `run_once.rb` with `--harness` option**: | ||||||
|
|
||||||
| To use it, run a benchmark script directly, specifying a harness directory with `-I`: | ||||||
| ```bash | ||||||
| ./run_once.rb --harness=perf benchmarks/railsbench/benchmark.rb | ||||||
| ./run_once.rb --harness=stackprof benchmarks/fib.rb | ||||||
|
|
||||||
| # With Ruby options (use -- separator) | ||||||
| ./run_once.rb -- --yjit benchmarks/railsbench/benchmark.rb | ||||||
| ./run_once.rb --harness=perf -- --yjit-stats benchmarks/fib.rb | ||||||
| ``` | ||||||
| ruby -Iharness benchmarks/railsbench/benchmark.rb | ||||||
|
|
||||||
| When using `run_benchmarks.rb`, you can specify a harness with the `--harness` option: | ||||||
|
|
||||||
| ```bash | ||||||
| ./run_benchmarks.rb --harness=once | ||||||
| ./run_benchmarks.rb --harness=perf | ||||||
| ``` | ||||||
|
|
||||||
| There is also a robust but complex CI harness in [the yjit-metrics repo](https://github.com/Shopify/yjit-metrics). | ||||||
|
|
||||||
| ### Chain harness | ||||||
|
|
||||||
| The `chain` harness allows you to combine multiple harnesses together. This is useful when you want to run a benchmark through multiple analysis tools or measurement approaches in sequence. | ||||||
|
|
||||||
| Use the `HARNESS_CHAIN` environment variable to specify which harnesses to chain (comma-separated, at least 2 required): | ||||||
|
|
||||||
| ```bash | ||||||
| # Chain the 'once' and 'default' harnesses (runs benchmark once, then with default iterations) | ||||||
| HARNESS=chain HARNESS_CHAIN="once,default" ruby benchmarks/fib.rb | ||||||
|
|
||||||
| # Profile with vernier while using ractor harness | ||||||
| HARNESS=chain HARNESS_CHAIN="vernier,ractor" ruby benchmarks-ractor/some_benchmark.rb | ||||||
|
|
||||||
| # Using run_once.rb | ||||||
| HARNESS_CHAIN="once,default" ./run_once.rb --harness=chain benchmarks/fib.rb | ||||||
| ``` | ||||||
|
|
||||||
| The harnesses are executed in the order specified, with each harness wrapping the previous one. | ||||||
|
|
||||||
| ### Iterations and duration | ||||||
|
|
||||||
| With the default harness, the number of iterations and duration | ||||||
|
|
@@ -250,26 +298,27 @@ You can also use `--warmup`, `--bench`, or `--once` to set these environment var | |||||
| ./run_benchmarks.rb railsbench --once | ||||||
| ``` | ||||||
|
|
||||||
| There is also a handy script for running benchmarks just once using | ||||||
| `WARMUP_ITRS=0 MIN_BENCH_ITRS=1 MIN_BENCH_TIME=0`, for example | ||||||
| with the `--yjit-stats` command-line option: | ||||||
| You can also run a single benchmark directly with Ruby: | ||||||
|
|
||||||
| ``` | ||||||
| ./run_once.sh --yjit-stats benchmarks/railsbench/benchmark.rb | ||||||
| ```bash | ||||||
| # Run once with YJIT stats | ||||||
| ruby --yjit-stats benchmarks/railsbench/benchmark.rb | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| # Or use run_once.rb script | ||||||
| ./run_once.rb -- --yjit-stats benchmarks/railsbench/benchmark.rb | ||||||
| ``` | ||||||
|
|
||||||
| ### Using perf | ||||||
|
|
||||||
| There is also a harness to use Linux perf. By default, it only runs a fixed number of iterations. | ||||||
| If `PERF` environment variable is present, it starts the perf subcommand after warmup. | ||||||
|
|
||||||
| ```sh | ||||||
| ```bash | ||||||
| # Use `perf record` for both warmup and benchmark | ||||||
| perf record ruby --yjit-perf=map -Iharness-perf benchmarks/railsbench/benchmark.rb | ||||||
| HARNESS=perf perf record ruby --yjit-perf=map benchmarks/railsbench/benchmark.rb | ||||||
|
|
||||||
| # Use `perf record` only for benchmark | ||||||
| PERF=record ruby --yjit-perf=map -Iharness-perf benchmarks/railsbench/benchmark.rb | ||||||
| ``` | ||||||
| HARNESS=perf PERF=record ruby --yjit-perf=map benchmarks/railsbench/benchmark.rb | ||||||
|
|
||||||
| This is the only harness that uses `run_benchmark`'s argument, `num_itrs_hint`. | ||||||
|
|
||||||
|
|
||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| require_relative '../harness/loader' | ||
| require_relative '../lib/harness/loader' | ||
|
|
||
| def fib(n) | ||
| if n < 2 | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| require_relative '../harness/loader' | ||
| require_relative '../lib/harness/loader' | ||
|
|
||
| class TheClass | ||
| def initialize | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't run a single iteration so it's not "once", unlike the
./run_once.sh --yjit-stats benchmarks/railsbench/benchmark.rbbefore. Trivial to fix: #446 (comment)