diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-02 10:58:21 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-02 10:58:21 -0400 |
| commit | 002e3d7d13c414ea874abbee8d82803dd3a72fe5 (patch) | |
| tree | 6627c12fa07f6a1cf73e5aaeb7390e698dd3a896 /debug/risc-v-gsp-rm-vm/examples/scripts/sim_bench.py | |
| parent | 2f249817df327f5dcccf0464ad517fa60d6071d3 (diff) | |
| download | open-iov-002e3d7d13c414ea874abbee8d82803dd3a72fe5.tar.gz open-iov-002e3d7d13c414ea874abbee8d82803dd3a72fe5.zip | |
debug: green-eye wave 3 - RM harness, local simulator, device map, MCP plugin, value-validation demos, CI pipeline, toolchain docs; add host RM tools rmtool/rmtop
Diffstat (limited to 'debug/risc-v-gsp-rm-vm/examples/scripts/sim_bench.py')
| -rw-r--r-- | debug/risc-v-gsp-rm-vm/examples/scripts/sim_bench.py | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/debug/risc-v-gsp-rm-vm/examples/scripts/sim_bench.py b/debug/risc-v-gsp-rm-vm/examples/scripts/sim_bench.py new file mode 100644 index 0000000..fa805ad --- /dev/null +++ b/debug/risc-v-gsp-rm-vm/examples/scripts/sim_bench.py @@ -0,0 +1,75 @@ +"""Measure native (M1) simulator throughput on the bundled demo firmware. + +Run standalone (from anywhere): + + python3 examples/scripts/sim_bench.py # untraced baseline + python3 examples/scripts/sim_bench.py --trace # baseline + R4 trace overhead + +Reports MIPS for a fixed instruction budget -- the budget +``SimClient.continue_(timeout=1.0)`` derives from SIM_IPS = 1e6. With +``--trace`` a second run enables the exec/access trace and reports the +per-instruction slowdown, so the non-trace path can be checked for regressions. +""" +from __future__ import annotations + +import argparse +import sys +import time +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[2] +if str(ROOT) not in sys.path: + sys.path.insert(0, str(ROOT)) + +import greeneye as ge +from greeneye.errors import RspTimeout +from sim.trace import Trace + +DEMO = ROOT / "firmware" / "uproc_demo" / "build" / "uproc_demo.elf" + + +def measure(budget: int, *, trace: bool = False) -> tuple[int, float]: + """Run a fixed instruction budget; return (instructions, seconds).""" + session = ge.launch(kernel=str(DEMO), backend="native", name="sim-bench") + machine = session.client.machine + if trace: + session.client.trace = Trace() # recorder stays null: nothing is written + try: + machine.insns = 0 + started = time.perf_counter() + try: + session.client.continue_(timeout=budget / 1_000_000.0) + except RspTimeout: + pass # budget exhausted: the benchmark workload completed + elapsed = time.perf_counter() - started + banner = session.target.read_uart().splitlines() + print(f"uart: {banner[0] if banner else '<empty>'!r}") + return machine.insns, elapsed + finally: + session.close() + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=__doc__.splitlines()[0]) + parser.add_argument("--budget", type=int, default=1_000_000) + parser.add_argument("--trace", action="store_true", help="also measure traced throughput") + parser.add_argument("--trace-budget", type=int, default=200_000) + args = parser.parse_args(argv) + + insns, elapsed = measure(args.budget) + mips = insns / elapsed / 1e6 if elapsed else float("inf") + print(f"native M1: {insns} instructions in {elapsed:.3f}s = {mips:.2f} MIPS (untraced)") + + if args.trace: + t_insns, t_elapsed = measure(args.trace_budget, trace=True) + t_mips = t_insns / t_elapsed / 1e6 if t_elapsed else float("inf") + overhead = (mips / t_mips - 1.0) if t_mips else float("inf") + print( + f"native M1 trace: {t_insns} instructions in {t_elapsed:.3f}s = {t_mips:.2f} MIPS " + f"({overhead * 100:+.1f}% per-instruction vs untraced)" + ) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) |
