docs(profiling): document screenshot/PNG trap; add full-loop workload
- docs/profiling.md: new "Profiling the render path" section — headless step() doesn't render; automation.screenshot() forces a render but PNG encoding then dominates (~96% of instructions in libsfml stbi_zlib_compress), burying engine work. Guidance: profile update/animation with step()-only, subtract stbi_* for the render path. Alludes to the Hybrid Scene Serialization wiki proposal (QOI + UI-tree serialization) as a faster capture path that would also de-noise screenshot-driven profiling. - tests/benchmarks/profile_workload.py: reusable full-loop driver (textured grid + moving entities + animated nested UI, forced renders). This is the workload that surfaced #348. Refs #345, #348. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
03c9b9ff58
commit
ef0408e06e
2 changed files with 119 additions and 0 deletions
|
|
@ -52,6 +52,31 @@ counts). Because it's deterministic, any delta is the change, not noise. `kcache
|
|||
Caveat: Callgrind models an idealized cache and counts instructions, not wall-clock —
|
||||
great for "did this do less work," not for real-time behavior.
|
||||
|
||||
## Profiling the render path — and the screenshot/PNG trap
|
||||
|
||||
In headless mode `mcrfpy.step()` does **not** render (the render path is stubbed); the
|
||||
only way to force a real render is `automation.screenshot()`, which flushes the
|
||||
off-screen target to a PNG. That has a sharp consequence for profiling: **PNG encoding
|
||||
dominates the profile**. On a representative full-loop workload, ~96% of instructions
|
||||
landed in libsfml's `stbi_zlib_compress` / `stbiw__encode_png_line` — the actual engine
|
||||
render/update/animation work was buried under 3%.
|
||||
|
||||
Implications:
|
||||
|
||||
- To profile **update / animation** logic, use a `step()`-only workload with **no**
|
||||
screenshots — the render cost (and the PNG artifact) is absent, so engine work is the
|
||||
whole profile.
|
||||
- To profile the **render path** itself, expect to subtract the PNG cost (filter out
|
||||
`stbi_*` / libsfml-graphics symbols) or drive rendering by another means.
|
||||
- The per-frame PNG cost is an artifact of the screenshot *serialization format*, not of
|
||||
rendering. A faster capture path (e.g. QOI encoding, plus a McRogueFace-specific UI-tree
|
||||
serialization) is explored in the wiki proposal
|
||||
[Hybrid Scene Serialization](https://dev.ffwf.net/forgejo/john/McRogueFace/wiki/Proposal%3A-Hybrid-Scene-Serialization);
|
||||
if adopted it would also make screenshot-driven profiling far less noisy.
|
||||
|
||||
A ready full-loop workload (textured grid + moving entities + animated nested UI, with
|
||||
forced renders) lives at `tests/benchmarks/profile_workload.py`.
|
||||
|
||||
## perf — real wall-clock sampling
|
||||
|
||||
For the interactive game where you need actual time spent (draw calls, SFML/Python cost
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue