perf(diag): complete trustworthy Slice A capture tooling

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>
This commit is contained in:
Erik 2026-07-24 12:46:51 +02:00
parent bf7ec12f68
commit 3ee8ec537a
23 changed files with 1639 additions and 170 deletions

View file

@ -0,0 +1,113 @@
# 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`](2026-07-24-performance-reference-configuration.json).
## Connected captures
Build once from a clean tracked worktree:
```powershell
dotnet build AcDream.slnx -c Release
```
Run the capped nine-stop route:
```powershell
.\tools\run-connected-r6-soak.ps1 `
-Repository (Get-Location).Path `
-SkipBuild `
-CaptureContention
```
Run the uncapped nine-stop route:
```powershell
.\tools\run-connected-r6-soak.ps1 `
-Repository (Get-Location).Path `
-SkipBuild `
-Uncapped
```
Run the pinned uncapped Arwic scene:
```powershell
.\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.Runtime` counters 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:
```powershell
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:
```powershell
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.

View file

@ -0,0 +1,74 @@
{
"schemaVersion": 1,
"recordedUtc": "2026-07-24T00:00:00Z",
"referenceHardware": {
"cpu": {
"name": "AMD Ryzen 7 9800X3D 8-Core Processor",
"physicalCores": 8,
"logicalProcessors": 16
},
"memoryBytes": 34359738368,
"gpu": {
"name": "AMD Radeon RX 9070 XT",
"driverVersion": "32.0.31021.5001"
},
"os": {
"name": "Microsoft Windows 11 Pro",
"version": "10.0.26200",
"build": "26200",
"architecture": "x64"
},
"dotnetSdk": "10.0.300"
},
"displayPaths": {
"authoritativeLocal": {
"adapter": "AMD Radeon RX 9070 XT",
"desktopResolution": "2560x1440",
"refreshHz": 240,
"authority": "performance-gate"
},
"diagnosticRdp": {
"adapter": "Microsoft Remote Display Adapter",
"desktopResolution": "2056x1290",
"refreshHz": 32,
"authority": "diagnostic-only"
}
},
"clientConfiguration": {
"build": "Release",
"windowMode": "windowed",
"renderResolution": "1280x720",
"quality": "High",
"fieldOfViewDegrees": 60,
"vsync": false,
"retailUi": true,
"developerUi": false,
"audio": true,
"datSource": "local retail EoR DAT files",
"server": "local ACE"
},
"routes": {
"canonicalNineStop": "tools/connected-r6-soak.route.txt",
"denseTown": {
"name": "Arwic",
"route": "tools/connected-dense-town.route.txt",
"arrival": "ACE canonical /telepoi Arwic position and heading",
"camera": "six seconds of MovementTurnRight after materialization",
"timeOfDay": 0.5
}
},
"screenshotComparison": {
"channelTolerance": 2,
"maxDifferentPixelFraction": 0.001,
"timeOfDay": 0.5,
"dynamicPixelRule": "Particles and other nondeterministic dynamic pixels must be excluded by an explicit same-resolution alpha mask. An unmasked failure is never waived by increasing the global tolerance."
},
"baselineRules": [
"Capped-local, uncapped-local, capped-RDP, and uncapped-RDP captures are separate populations and are never compared as if interchangeable.",
"Only an authoritative-local capture may establish or pass FPS, CPU, GPU, or frame-time budgets.",
"RDP captures may validate automation, lifetime, allocation attribution, and large regressions, but are labeled diagnostic-only.",
"Re-baseline after a CPU, GPU, driver, OS build, physical display path, render resolution, quality, FOV, VSync, DAT set, route, or measurement-schema change.",
"A re-baseline records the source commit and keeps the prior committed baseline for historical comparison unless its data is invalid.",
"Performance captures use a clean tracked worktree and disclose all ACDREAM_* launch variables with secrets redacted."
]
}

View file

@ -0,0 +1,22 @@
# Performance reference configuration
The machine-readable contract is
[`2026-07-24-performance-reference-configuration.json`](2026-07-24-performance-reference-configuration.json).
It fixes the reference CPU/GPU/driver/OS, graphical settings, routes, display
paths, screenshot rule, and re-baseline policy used by the Modern Runtime
Architecture plan.
Only the physical AMD display path is authoritative for frame-time, CPU, and
GPU acceptance gates. Remote Desktop runs are intentionally retained as a
separate diagnostic population: they validate the connected route, resource
lifetime, allocation attribution, and major regressions, but the 32 Hz remote
presentation path cannot establish maximum throughput.
The connected routes pin the client-only world-time override at noon. The
dense-town route uses ACE's canonical Arwic point-of-interest arrival and a
fixed six-second retail-input turn before its screenshot and checkpoint.
Screenshot comparison uses a per-channel tolerance of 2 and permits at most
0.1% differing unmasked pixels. Dynamic particles or similarly nondeterministic
pixels require an explicit same-resolution alpha mask; a failure is not
accepted by silently increasing the global tolerance.