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:
parent
bf7ec12f68
commit
3ee8ec537a
23 changed files with 1639 additions and 170 deletions
113
docs/research/2026-07-24-performance-capture-playbook.md
Normal file
113
docs/research/2026-07-24-performance-capture-playbook.md
Normal 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.
|
||||
|
|
@ -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."
|
||||
]
|
||||
}
|
||||
|
|
@ -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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue