docs(perf): dense-town FPS — final outcome (75->165) + ISSUES record

Report: OUTCOME section (the two shipped fixes, the glFinish-artifact correction,
the deliberately-unpursued scenery-CPU/terrain-GPU headroom). ISSUES: recently-
closed entry with SHAs + pointers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-24 00:13:32 +02:00
parent a9d06a613a
commit 02578ddb74
2 changed files with 45 additions and 0 deletions

View file

@ -5438,6 +5438,19 @@ outdoors at the angle that previously erased it.
# Recently closed
## Dense-town (Arwic) FPS deep-dive — 75 → ~165 fps
**Status:** DONE (2026-06-24) — `290e731` (cell-object draw batching) + `9f51a4d`
(cell-particle consolidation, also fixed a latent additive double-draw in
multi-aperture cells); apparatus stripped `a9d06a6`. Pixels-identical, build +
full suite green. **The handoff's "GPU-bound / ~12 ms GPU" was wrong** — that was a
glFinish self-measurement artifact; real GPU ~0.5 ms, the frame is ~96 % CPU-bound
(per-cell rebuild cost scaling with visible buildings). Remaining headroom
(scenery-CPU `WbDrawDispatcher` rebuild ~2.1 ms + terrain-GPU ~2.1 ms) deliberately
NOT pursued — both in frozen load-bearing subsystems, HIGH risk for ~15 fps at one
extreme view already over target. SSOT: `docs/research/2026-06-23-dense-town-fps-attribution-report.md`.
Lessons: `memory/feedback_render_perf_measurement.md`.
## #113 — Phantom staircase: REOPENED 2026-06-11, folded into the HOLISTIC BUILDING-RENDER PORT
**Status:** REOPENED — root cause #2 found (drawing-BSP-orphaned no-draw polys:

View file

@ -13,6 +13,38 @@ decisive runs are listed in §6 for the user to drive.
---
## OUTCOME (FINAL — shipped 2026-06-24)
Dense Arwic: **75 → ~165 fps** (steady; ~130 at the absolute densest standing-still
view — over the 144 target except that one extreme). Two isolated, verified,
pixels-identical fixes (render-perf is not faithfulness-gated):
1. **Cell-object draw batching** (`290e731`) — `DrawCellObjectLists` collapsed N
per-cell `WbDrawDispatcher.Draw` calls into one cross-cell batched draw
(`cellobjects` 3.5 → ~0.4 ms).
2. **Cell-particle consolidation** (`9f51a4d`) — the per-cell `DrawCellParticles`
re-walk (O(cells×particles)) collapsed into one union pass; also fixed a latent
additive **double-draw** in multi-aperture cells.
Throwaway profiling apparatus stripped (`a9d06a6`). Build + full suite green.
**The handoff's framing was wrong, and is corrected here:** the dense town was
NEVER GPU-bound. The "~12 ms GPU" was a **glFinish self-measurement artifact** (the
profiler's own pipeline flushes inflated its number); the true GPU is ~0.5 ms
standing still. The frame is **~96 % CPU-bound**, and the cost scales with how many
buildings are in view.
**Remaining headroom — deliberately NOT pursued (user-approved finalize):** the last
~2.1 ms CPU is `WbDrawDispatcher`'s per-frame static-scenery rebuild (`ls.scenery`);
~2.1 ms GPU is terrain rasterization (`ls.terrain`). Both live in FROZEN,
load-bearing subsystems. The only way to fully cut scenery-CPU is a cross-frame
cache of the entity dispatcher — judged HIGH risk (regresses ALL entity rendering if
mis-keyed; the #53/#119/#128 bug class; thrashes on the eye's rest-jitter) for ~15
fps at one extreme view already over target. The safe micro-opts net only ~0.3 ms.
Full analysis: §0b + the dispatcher-investigation workflow.
---
## 0a. MEASURED VERDICT — clean split, `ACDREAM_FPS_PROF=2` (2026-06-23, live Arwic)
The hypothesis below was **confirmed by direct measurement.** Added a diagnostic