Skip to content

perf(memory): skip 4 MiB runs no write stamped since a range check - #6266

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
meh7an:perf/memory-coarse-write-stamps
Oct 18, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
meh7an:perf/memory-coarse-write-stamps

Conversation

@meh7an

@meh7an meh7an commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

What

GuestMemory::UnchangedSince and UnchangedSinceAll answer whether any 64 KiB block of a range was stamped after a generation. #1310 made that a tight scan of the block stamps, but the scan still reads every block of the range. Render targets are checked this way on every draw (StorageTexture::refreshProved, from refreshResidentTarget), and a 4K surface spans hundreds of blocks.

The write tracker now also keeps the newest stamp of each run of 64 blocks (4 MiB), and stamp raises it with the block's stamp. unchanged skips a whole run whose newest stamp is not after the generation. It scans the other runs, and the partial runs at either end, block by block as before.

  • Only initialize and stamp write block stamps, so a run's stamp cannot fall behind its blocks.
  • On Linux a run never crosses a leaf, because 64 divides LeafBlocks.

On the S2 page of Sonic Origins Plus's main menu, UnchangedSince cost the queue worker (APS5 sampler, 15 s):

  • before, in two runs: 62 and 86 samples, of which 47 and 60 were its own scan;
  • with this change: 50 samples, of which 31 were its own scan.

Per frame that is 0.76 to 0.44 samples. That is about 0.6% of the worker's frame, so the frame times below move within run-to-run noise.

Tested

Windows 11 (10.0.26300), WinLibs GCC 15.2.0 (UCRT), Release, NVIDIA GeForce RTX 2080 Ti, driver 617.14.

  • On main db81992 with this change, the full ctest suite passes: 1253 of 1254 tests. The other one, agc_driver_draw_program_trace, is not run, because its test executable does not link under MinGW on main itself (__gxx_personality_v0 is undefined); it does not contain the code changed here.
    • agc_write_tracking has a new check, CheckCoarseRuns, over a range of 192 blocks. A driver store inside whole runs and a CPU store into the last block must both be seen, and blocks outside the stored one must stay unchanged.
    • The check fails ("a driver store inside whole 4 MiB runs of the range is not seen") when stamp leaves the run stamp alone.
  • Sonic Origins Plus, main menu, S2 page (the 3D background), 1233x694 window.
    • Captured with APS5_TRACE_SECONDS=200:15 on the same machine in one session, caches warm. Traces attached.
    • Baseline b593e36, this change b8acbb0 (its summary says a38ad5e, see the note):
Metric Baseline This PR Change
frame_ms.p50 130.365 130.139 -0.2%
frame_ms.p90 136.606 132.568 -3.0%
mean_frame_ms 133.147 130.258 -2.2%
gpu_busy_ms_per_present 83.817 85.039 +1.5%
Driver.Packet (ms per frame) 130.567 127.684 -2.2%

The median frame did not move. The mean and p90 differences come mostly from a few slow frames in the baseline's window (p99 160.8 against 135.1 ms), which is run-to-run noise at this size.

The FPS shown in the title went from 7.91 to 8.34 (median of six readings). The sampled pair, run an hour earlier, showed 7.55 and 7.51, so neither pair moves beyond run-to-run noise.

Note: measuring base. These numbers come from my fork's dev, on main 0a56aaa, the last main before #5596. On Windows, later mains compare direct imports on every use, which keeps this menu at 3-4 FPS and hides a change of this size.

Both carry these commits from my fork:

The comparison tool marks the window's first present (2398 vs 2422) as a configuration difference: the window opens 200 s into each run. Both summaries set trace_dropped, because the worker filled its event buffer at about 2,700 draws per frame. The phase totals above stay complete. The change's summary says a38ad5e with dirty, because that build was made from the change's tree before it was committed as b8acbb0.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Unblocks: none
  • GPUs tested: NVIDIA GeForce RTX 2080 Ti, driver 617.14, Windows 11
  • AI-assisted: yes

Traces and summary lines (baseline b593e36, this change b8acbb0, whose summary says a38ad5e):
coarse-traces.zip

@github-actions github-actions Bot added the agc libSceAgc* label Oct 15, 2026
This was referenced Oct 15, 2026
@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 6701 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp L808-820, L825, L859-860, L1056-1065, L1070, L1085-1093

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 4448 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 5021 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6185 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6186 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6188 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6192 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6234 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6273 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/tests/WriteTracking.cpp
PR 6868 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/tests/WriteTracking.cpp
PR 6946 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6947 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 7201 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/tests/WriteTracking.cpp
PR 7332 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/tests/WriteTracking.cpp
PR 7615 core/libs/prx/libSceAgcDriver/tests/WriteTracking.cpp
PR 7642 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 18, 2026
@adriadam10 adriadam10 self-assigned this Oct 18, 2026
@adriadam10
adriadam10 force-pushed the perf/memory-coarse-write-stamps branch from b594d57 to 192d95c Compare October 18, 2026 19:35
@github-actions github-actions Bot added perf Performance change perf numbers missing perf pull request without a before and after summary line labels Oct 18, 2026
@github-actions

Copy link
Copy Markdown

This pull request is labeled perf, so it needs the summary line of a capture on main and one with the change, from the same title, scene and machine, as the Performance report form asks. Please paste both aps5-summary.jsonl lines, attach the two traces and add the output of tools/trace_digest.py.

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 18, 2026
@adriadam10
adriadam10 merged commit defd27a into boykopovar:main Oct 18, 2026
10 checks passed
TheBlenDed pushed a commit to TheBlenDed/AnyPS5 that referenced this pull request Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* perf numbers missing perf pull request without a before and after summary line perf Performance change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants