Adds a tiny zone-based profiler (prof.{h,cpp}) enabled via KOBO_PROF=1.
Instruments run_game with zones for myship.move, enemies.move (split into
realize and move_pass), hit_structure, and hit_bolt. Adds KOBO_STRESS=N
to keep the enemy pool topped up with rocks for stable per-frame timing.
Why: the entity/render pipeline refactor in BENCH.md needs a comparable
baseline before any layout changes. Without a stress workload the natural
gameplay enemy count is too noisy to compare across commits.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
55 lines
2.8 KiB
Markdown
55 lines
2.8 KiB
Markdown
# Kobo Deluxe DOD Refactor — Benchmark Scoreboard
|
|
|
|
Each row is one phase of the refactor (see
|
|
`~/.claude/plans/can-you-explain-the-noble-wilkes.md`). Numbers are median
|
|
ns/frame from `KOBO_PROF=1 KOBO_STRESS=1500 ./build/kobodl`, ~1000 frames,
|
|
release build (`-O2 -g`).
|
|
|
|
## How to capture a baseline
|
|
|
|
```sh
|
|
cd build
|
|
cmake --build . -j
|
|
KOBO_PROF=1 KOBO_STRESS=1500 ./kobodl
|
|
# play through a stage; profile dumps every 600 frames to stderr.
|
|
# Redirect stderr to a file if you want to keep it:
|
|
KOBO_PROF=1 KOBO_STRESS=1500 ./kobodl 2>prof.log
|
|
```
|
|
|
|
The profiler dumps a table per zone with `calls`, `total_ms`, `ns/call`.
|
|
Record the `ns/call` for these zones (they are the moving parts the refactor
|
|
targets):
|
|
|
|
| Zone | What it measures |
|
|
|-----------------------|-----------------------------------------------------|
|
|
| `run_game` | Full game tick |
|
|
| `myship.move` | Player + bolt update |
|
|
| `enemies.move` | Realize pass + move pass combined |
|
|
| `enemies.realize` | Just the realize-reserved pass |
|
|
| `enemies.move_pass` | Just the per-enemy move pass (the hot loop) |
|
|
| `hit_structure` | Player vs map + bolt vs map |
|
|
| `hit_bolt` | Bolt-vs-enemy scan (called from inside enemy move) |
|
|
|
|
## Scoreboard
|
|
|
|
| Phase | run_game | myship.move | enemies.move_pass | hit_bolt | Notes |
|
|
|------------------------------|---------:|------------:|------------------:|---------:|-------|
|
|
| 0 — baseline | ? | ? | ? | ? | TBD — user to capture |
|
|
| 1 — hot/cold split | | | | | |
|
|
| 2 — SoA pool | | | | | |
|
|
| 3 — bucket dispatch | | | | | |
|
|
| 4 — flipped bolt collision | | | | | |
|
|
| 5 — render decouple | | | | | |
|
|
| 6 — SIMD integrator (opt.) | | | | | |
|
|
|
|
## Notes
|
|
|
|
- `KOBO_STRESS=N` keeps the pool topped up with rocks; N=1500 sits well
|
|
below ENEMY_MAX=2048 so the spawner doesn't thrash on full-pool checks.
|
|
- The stress spawner uses `pubrand`, which is acceptable for benchmarking
|
|
but will *not* produce identical demos across builds — that's fine, we
|
|
only care about steady-state cost.
|
|
- For a stable run, start the game, get into a stage, then let it sit for
|
|
~1000 frames before reading numbers. The first dump (frame 600) will
|
|
include startup costs and should be discarded.
|