Mission loads 72s -> 4s: the wait screen was GPU-syncing every idle frame
The operator challenged the "inevitable ~minute" load (Task Manager showed idle CPU) and was right. Measured chain: - A/B same box/egg: dev 7s, +glass 30s, +BT_DEV_GAUGES 72s+. - Drain census: identical ~560-event make streams; 190 events/s in dev vs a metronomic 7/s in the console shape -- the loop, not the events. - Stack sampling: 4/6 samples inside ExecuteIdle's wait-screen paint -- GDI GetDC/FillRect on the D3DPOOL_DEFAULT offscreen surface forces a full GPU pipeline sync (~140ms/frame at glass window size). The 2026-07-22 flicker fix traded a cosmetic bug for a 25x load throttle, worst on the operator box (bigger window + gauge-window GPU work), with idle CPU because a GPU-sync stall isn't compute. Fix (ExecuteIdle): the staging surface is D3DPOOL_SYSTEMMEM (GetDC is pure CPU; survives Reset for free) uploaded via UpdateSurface, and a change gate skips the whole idle frame unless the spinner phase (12.5Hz) or state text changed -- between paints the loop runs free. Result: console-shape load 72s+ -> 4.1s (BEGIN -> READY), drain at 345 events/s; every pod benefits (same code), and the all-ready launch gate now waits on a seconds-scale slowest loader. Permanent pre-run diagnostics kept: the drain census + >50ms slow-event lines (EVENT.cpp, stand down at scene-live; slow-event identity captured BEFORE Process -- Receiver::Receive(Event*) deletes the event). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
87ef6a85f9
commit
56ca2f5c13
+20
-1
@@ -437,7 +437,26 @@ phase). Plan: `~/.claude/plans/partitioned-snuggling-piglet.md`.
|
||||
from take 2's commit is UNPROVEN -- the measured fact is just that loads outlive any fixed
|
||||
cap; the counter design is correct under either reading. Residual: WHY loads take 1-2+ min
|
||||
on the operator box (vs ~30s earlier same day) is an open perf question ([loadobj] timings).
|
||||
- **WHERE THE LOAD MINUTE GOES (2026-07-22) [T2, measured]**: teal->green (egg receipt ->
|
||||
- **THE LOAD MINUTE -- SOLVED (2026-07-23) [T2, measured end-to-end]**: the operator challenged
|
||||
the "inevitable ~minute" claim (idle CPU in Task Manager) and was RIGHT. A/B on the same
|
||||
box/egg: dev profile 7s, +glass 30s, +BT_DEV_GAUGES 72s+ -- the layers, not the machine.
|
||||
Drain census (`[loadphase] drained N events/s`, EVENT.cpp pre-run): IDENTICAL ~560-event
|
||||
streams, 190/s in dev vs a metronomic **7/s** in the console shape. Stack sampling (cdb,
|
||||
6 samples): 4/6 inside ExecuteIdle's wait-screen paint -- **GDI GetDC/FillRect on the
|
||||
D3DPOOL_DEFAULT offscreen surface forces a full GPU pipeline sync (~140ms/frame at glass
|
||||
window size)**, i.e. the 2026-07-22 flicker fix traded a cosmetic bug for a 25x load
|
||||
throttle (bigger glass window + gauge-window GPU work made it worst on the operator box;
|
||||
idle CPU because a GPU sync stall isn't compute). FIX (L4VIDEO ExecuteIdle): the staging
|
||||
surface is now **D3DPOOL_SYSTEMMEM** (GetDC = pure CPU) uploaded via `UpdateSurface`
|
||||
(StretchRect can't take sysmem), and a **change gate** skips the entire idle frame unless
|
||||
the spinner phase (12.5Hz) or text changed -- between paints the loop runs free. RESULT:
|
||||
console-shape load **72s+ -> 4.1s** (BEGIN->READY), drain 345 events/s; benefits EVERY pod
|
||||
(same code everywhere) + the all-ready gate now waits on a seconds-scale slowest loader.
|
||||
The earlier "renderers' entity-make streams are the minute" reading was the RIGHT queue but
|
||||
the WRONG cost: the events were cheap; the loop offering them was throttled. Diagnostics
|
||||
kept permanently: drain census + >50ms slow-event lines (EVENT.cpp, pre-run only, stand
|
||||
down at scene-live).
|
||||
- **WHERE THE LOAD MINUTE GOES (2026-07-22) [T2, measured -- superseded above]**: teal->green (egg receipt ->
|
||||
WaitingForLaunch/READY) measured 58s on the operator box uncontended, ~28s on a quieter run.
|
||||
Attribution (loadphase markers + queue dump): renderer LoadMission = **31ms**, model loads =
|
||||
**0.2s** -- essentially ALL the time is the LoadingMission ready-gate
|
||||
|
||||
Reference in New Issue
Block a user