tests/benchmarks: writing and running cage-rtt benchmarks#830
tests/benchmarks: writing and running cage-rtt benchmarks#830stupendoussuperpowers wants to merge 4 commits intomainfrom
tests/benchmarks: writing and running cage-rtt benchmarks#830Conversation
End-to-End Test ReportTest PreviewTest Report Deterministic TestsSummary
Test Results by Category
Fail TestsSummary
Test Results by Category
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Do we have some example data with this benchmark suite? |
|
It's in the README. Sample outputs: lind@232affd4dc4d:~/lind-wasm$ ./scripts/benchrunner.py fs_read imfs_grate.fs_read.grate
Running: /home/lind/lind-wasm/tests/benchmarks/fs_read.c
Running: /home/lind/lind-wasm/tests/benchmarks/imfs_grate.fs_read.grate
TEST PARAM LINUX (ns) LIND (ns) GRATE (ns) ITERATIONS
---- ----- ---------- ----------- ------------ ----------
Read 1 240 451 (1.879) 1102 (4.592) 1000000
Read 1024 252 461 (1.829) 1102 (4.373) 1000000
Read 4096 267 475 (1.779) 1149 (4.303) 1000000
Read 10240 389 586 (1.506) 1348 (3.465) 1000lind@232affd4dc4d:~/lind-wasm$ ./scripts/benchrunner.py -o result.json fs_read imfs_grate.fs_read.grate && jq . result.json
Running: /home/lind/lind-wasm/tests/benchmarks/fs_read.c
Running: /home/lind/lind-wasm/tests/benchmarks/imfs_grate.fs_read.grate
{
"Read": {
"1": {
"grate": "1043",
"lind": "448",
"linux": "237",
"loops": "1000000"
},
"1024": {
"grate": "1038",
"lind": "457",
"linux": "250",
"loops": "1000000"
},
"4096": {
"grate": "1088",
"lind": "469",
"linux": "265",
"loops": "1000000"
},
"10240": {
"grate": "1273",
"lind": "712",
"linux": "383",
"loops": "1000"
}
}
} |
|
I think the grate benchmarks are using the wrong register_handler API post #798 |
There was a problem hiding this comment.
- collect_tests globs * without filtering by .c suffix — will try to compile README.md, imfs.h, etc. and os._exit(1)
- Bare except: catches KeyboardInterrupt/SystemExit — should be except Exception:
There was a problem hiding this comment.
this always reports failure?
|
As discussed with @rennergade, instead of having grates duplicates in this benchmarks folder, I'll update the runner to just fetch them from the example grates repo like a quasi-package manager of sorts. |
|
Updated this to use the example grates repo to source grates. Added a PR to example grates repo as well to make sure it's set up to be used like that. Also update the test runner script for some better error handling (e.g. skip if compilation/run fails, print debug logs, etc.) |
End-to-End Test ReportTest PreviewTest Report Deterministic TestsSummary
Test Results by Category
Fail TestsSummary
Test Results by Category
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Child | ||
| if (pid == 0) { | ||
| close(sv[0]); | ||
| char buf[msg_size]; |
There was a problem hiding this comment.
char buf[msg_size] is a VLA on the child stack in uds_dgram. For KiB(32) that's 32KB on the stack, which is fine, but in uds_stream (line 75) the parent uses malloc while the child in uds_dgram uses VLA. Inconsistent — the commented-out VLAs (// char buf[msg_size]) suggest this was partially migrated.
|
|
||
| // Emits one benchmark row in the format: | ||
| // <test>\t<param>\t<loops>\t<avg_ns> | ||
| inline void emit_result(char *test, int param, long long average, int loops) { |
There was a problem hiding this comment.
emit_result is declared inline in the .c file but has external linkage via the header declaration. This can cause linker issues. Remove the inline keyword.
|
|
||
| def run_lind(wasm_paths, res, platform): | ||
| """Run lind-boot with one or more wasm paths.""" | ||
| cmd = ["sudo", "lind-boot"] + wasm_paths |
There was a problem hiding this comment.
probably worth calling lind_run?
| return rel.name | ||
|
|
||
|
|
||
| def parse_output(res, output, platform): |
There was a problem hiding this comment.
parse_output silently swallows parse errors. param is stored as int key in the dict but JSON serialization will convert it to a string key. When reading back, param keys won't match. Consider using string keys consistently.
| run_native(native_path, res) | ||
| elif test.suffix == ".grate": | ||
| print("Running: ", test) | ||
| status = run_grate_test(test.with_suffix(""), res) |
There was a problem hiding this comment.
run_grate_test returns None on success (no explicit return), so the if not status check on line 332 will always print "Failed to compile. Skipping." even on success.
rennergade
left a comment
There was a problem hiding this comment.
added some more comments.
probably want a .gitignore
Should think about factoring out the imfs code
End-to-End Test ReportTest PreviewTest Report Deterministic TestsSummary
Test Results by Category
Fail TestsSummary
Test Results by Category
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Addressed all the comments. Not sure about the parse_output one, since it does have a try/except block which logs when the output is malformed along with the output. |
End-to-End Test ReportTest PreviewUnified Test Report grate harness
Cases
wasm harnessTest ReportDeterministic TestsSummary
Test Results by Category
Fail TestsSummary
Test Results by Category
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- Add scripts/benchrunner.py as the test runner. - Add tests/benchmarks folder with benchmark source files. - Add tests/benchmarks/README.md to add details about the benchmarking test suite. - Address all comments on the PR. - Add a support for test descriptions. - Add support for .csv output.
41f2dd6 to
b7a9c59
Compare
End-to-End Test ReportTest PreviewUnified Test Report grate harness
Cases
wasm harnessTest ReportDeterministic TestsSummary
Test Results by Category
Fail TestsSummary
Test Results by Category
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||
| ### IMFS Tests | ||
| Example: `imfs_read.c` | ||
| These call IMFS functions directly to estimate in-memory FS overhead |
There was a problem hiding this comment.
Do we need to prepare the imfs_grate wasm binary before running the test? If so, what's the step? ie: we need to pull from example repo manually or..?
I also didn't find imfs_read.c in this PR..
There was a problem hiding this comment.
Need to update the readme, we are not doing independent imfs tests right now.
|
I tried to run the runner locally and it works well. I see there's a |
All grates are fetched from the lind-wasm-example-grates repo using a git shallow clone, the grates/ folder within the benchmarks folder is equivalent to As previously discussed, this was done so that we don't need to manually make changes to a grate we might want to benchmark in two separate places i.e. once in the example-grates repo and then once in this benchmarks folder. It therefore should not be committed. |
JustinCappos
left a comment
There was a problem hiding this comment.
Need to board a flight. Will try to look more later
| def repo_root() -> Path: | ||
| """Return repo root (scripts/..).""" | ||
| return Path(__file__).resolve().parent.parent |
There was a problem hiding this comment.
Does this do what the comment says? Doesn't it resolve to ../.. from the script itself instead?
There was a problem hiding this comment.
Will change the doc string it's a bit confusing.
It's supposed to mean => benchrunner.py is in the scripts/ folder (Path(__file__).parent), the root of the lind-wasm repo is scripts/..
| str(GRATES_REPO_DIR), | ||
| ] | ||
| ) | ||
| run_cmd(["git", "-C", str(GRATES_REPO_DIR), |
There was a problem hiding this comment.
The way in which you checkout things here seems odd to me. Might these be better off in the same repo or with them as cargo packages with explicit dependenciet?
There was a problem hiding this comment.
We need to fetch grates from somewhere and right now we use the lind-wasm-example-grates repo as the single source of truth for them. So we need to do quasi-package manager things for this. Ideally I guess we'd have each grate set up as a crates.io entry or as a packaged release on github for C grates, but none of that is set up currently.
| if status: | ||
| existing = [ | ||
| line.strip() | ||
| for line in status.stdout.decode("utf-8").splitlines() | ||
| if line.strip() | ||
| ] |
There was a problem hiding this comment.
I'm not that sure what you are doing here. What is considered existing? Does a directory existing count? Does it need to be bit for bit identical with all files, etc.?
There was a problem hiding this comment.
We use sparse checkouts to grab only the grate that was requested, this just check if our git config has already registered this folder for that sparse checkout.
If not, it adds it to the list
Latest changes are pulled regardless, on L140
| add_sparse_path(f"examples/{grate_name}") | ||
| repo_path = GRATES_EXAMPLES_DIR / grate_name |
There was a problem hiding this comment.
Seems like this should be a constant both places, right?
There was a problem hiding this comment.
repo_path will be grates/imfs-grate or grates/geteuid-grate etc, depending on which grate is being fetched. The only constant is the base path encoded in GRATES_EXAMPLES_DIR
|
|
||
| #define LOOP_COUNT 1000000 | ||
|
|
||
| int main(int argc, char *argv[]) { |
There was a problem hiding this comment.
There is a lot of duplication across the tests. Would you be better off having them be more modular and included instead of duplicating all of the main, etc. code?
There was a problem hiding this comment.
I tried to trim down some of these tests, right now I do not want to over-engineer helpers around these benchmarks so I've tried to keep each benchmark as standalone as possible. Can look into building something more sophisticated as we add more tests.
End-to-End Test ReportTest PreviewUnified Test Report grate harness
Cases
wasm harnessTest ReportDeterministic TestsSummary
Test Results by Category
Fail TestsSummary
Test Results by Category
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
The previous data measured and reported in #718 was done for the most part with a hacky and temporary script that needed manual intervention at various points.
This PR adds all the tests used in the Performance Tracker (+ IPC tests) with a runner.
Changes:
tests/benchmarkfolder which contains source code for benchmarking testsbenchrunner.pyto compile, run, and aggregate the results to either print to the terminal or store as ajsonREADME.mddetailing how these tests are run, and how to add new tests