Correct whole-frame GPU timestamps so they bracket only the accepted render transaction and associate delayed query results with the owning CPU frame. Add route-wide frame-history summaries, fixed-camera screenshot comparison, process counters, contention traces, a pinned Arwic workload, and credential-safe launch disclosure. The reference hardware/display contract now keeps local and RDP populations separate and defines the screenshot and re-baseline rules needed by later prepared-content gates. Co-Authored-By: Codex <noreply@openai.com>
3.7 KiB
Performance capture playbook
This is the reproducible Slice A capture procedure for the Modern Runtime
Architecture plan. The machine and graphical contract is
2026-07-24-performance-reference-configuration.json.
Connected captures
Build once from a clean tracked worktree:
dotnet build AcDream.slnx -c Release
Run the capped nine-stop route:
.\tools\run-connected-r6-soak.ps1 `
-Repository (Get-Location).Path `
-SkipBuild `
-CaptureContention
Run the uncapped nine-stop route:
.\tools\run-connected-r6-soak.ps1 `
-Repository (Get-Location).Path `
-SkipBuild `
-Uncapped
Run the pinned uncapped Arwic scene:
.\tools\run-connected-r6-soak.ps1 `
-Repository (Get-Location).Path `
-SkipBuild `
-Uncapped `
-DenseTown
Credentials come from ACDREAM_TEST_USER and ACDREAM_TEST_PASS, or the
script's local test defaults. The generated environment disclosure redacts
secret-like variable names. Never commit credentials, raw stdout/stderr,
counter CSVs, .nettrace, or machine-local absolute paths.
Every run captures:
- Per-frame CPU, GL GPU, frame-thread allocation, and stage history.
- Route-wide and five-second checkpoint percentiles.
- Per-portal windows from 10 seconds before through 5 seconds after materialization, including the 20 worst frames.
- Process-wide
System.Runtimecounters at one-second cadence. - Canonical resource/checkpoint JSON and named screenshots.
- Optional CLR contention events with call stacks.
-SkipRuntimeCounters exists for measurement-overhead experiments only. A
baseline captured with it is incomplete.
Allocation and contention attribution
The per-frame history answers which frame and which update/upload phase was
expensive. Canonical checkpoint deltas and runtime-counters.csv answer
whether allocations were merely moved to workers.
For per-thread allocation stacks, make a separate reproduction capture so the observer cost is not mixed into the baseline:
dotnet-trace collect `
--process-id <pid> `
--providers Microsoft-Windows-DotNETRuntime:0x0000000000000001:5 `
--duration 00:00:00:30 `
--output allocation-stacks.nettrace
The provider enables CLR GC events at verbose level; inspect allocation-tick stacks grouped by managed thread in PerfView or Visual Studio. Interpret sampled bytes as attribution weights, not exact object sizes.
The soak's -CaptureContention mode captures the CLR contention keyword
(0x4000) at verbose level. Inspect ContentionStart call stacks and group by
lock acquisition site. The first comparisons are the DAT typed-object lock,
ObjectMeshManager pending-request ownership, and any newly dominant caller;
do not optimize a lock solely from event count.
Screenshot contract
Compare a candidate against the matching reference image:
dotnet .\src\AcDream.Cli\bin\Release\net10.0\AcDream.Cli.dll `
compare-screenshots `
<reference.png> `
<candidate.png> `
<comparison.json> `
2 `
0.001 `
<optional-mask.png>
The routes pin world time and camera input. A nonzero-alpha mask excludes known dynamic pixels such as DAT particles. Never widen the global tolerance to conceal a deterministic geometry, texture, visibility, or UI difference.
Baseline authority
Name every committed compact result capped-local, uncapped-local,
capped-rdp, or uncapped-rdp. RDP captures are diagnostic only for
throughput. An authoritative local baseline must be run on the physical AMD
display path defined in the reference configuration. A baseline report records
the exact commit and must have a clean tracked source status.