Repository navigation
perf(agc): memoize host import run bounds per lease snapshot - #6951
alfalfa-star wants to merge 1 commit into
Conversation
|
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.
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.
|
CnRJay
left a comment
There was a problem hiding this comment.
Default-off span mirror plus two changes that are on by default, and no measurement of any of them.
- The incremental import refresh (
APS5_NO_INCREMENTAL_IMPORT_REFRESH) and the run memo (APS5_NO_RUN_MEMO) change behaviour for every title on every host, and the registry change journal decides which imports get refreshed. A missed journal entry leaves an import pointing at a remapped range. Say what bounds the journal (what happens when it wraps, or when the registry changes during a refresh), and add a test where an allocation is unmapped and remapped between two refreshes and the next draw must see the new pages. - The udmabuf path is Linux-only and was tested on RADV only. Windows runs the same refresh and run-memo code; please run the
agc_*suite there and say so. APS5_SPAN_NO_FLUSH=1skips flushing pending GPU writes over the span before it is served. Leave that out of this PR, or show a title that needs it. A switch whose only effect is to serve stale data is not a performance feature.- 640 lines across the import code,
GuestAllocationsand the mirror in one PR; the mirror (off by default) and the refresh changes (on by default) are two topics and should be two PRs, so the default-on part can be measured and merged on its own. - "About 24 fps in our local test build" and "a measurement will follow" do not meet the Performance report form. Please add the summary lines of main and this PR, same scene in PPSA01802, once with
APS5_SPAN_MIRROR=1and once without, noAPS5_PROFILE_*.
|
Data point from a CPU-bound scene on Windows: RTX 3060 12 GB (NVIDIA 617.42), i5-12400F, Windows 10 19045, MinGW GCC Release. Minecraft Dungeons II (PPSA16064 01.100.100), title screen, no input, 200 s rows,
Within the run-to-run spread ( AI-assisted: yes (Claude Code) |
|
A profile from another title where this path is the largest committer cost; it doesn't measure this PR. Metal Gear Solid 4 (PPSA18194), Ubuntu 24.04, i7-13700K, RTX 4070 Ti (595.99.02), Release, pad input.
So most of it is the import refresh re-walking runs on each draw's input lookup, which your incremental refresh and per-lease run memo target. I haven't run this PR on MGS4 yet. I can if that's useful, but MGS4 needs those three PRs on top. AI-assisted: yes (Claude Code) |
Every import lookup walked the lease to find the run of registry ranges around an address. The bounds are now memoized per thread, keyed by the lease snapshot, the containing range and the import window, and checked against the first and last range before use; sameRange and the whole-run lookup in importAllocation use the bounds without building the run. APS5_NO_RUN_MEMO=1 turns the memo off. The test registers a range next to an imported one and requires the next build's import to cover both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
c7a43cc to
ae409e1
Compare
|
Thanks. I measured each part on its own, and the PR is now one topic. I force-pushed it down to the part that is on by default and measurably faster: the run memo ( Kena (PPSA01802), forest title scene, no input.
Windows: this version touches no Linux-only code. I can't run the Measurement of this version (rotated with another build; one run of each reached a lighter stretch with 48 ms GPU busy instead of about 80 and isn't comparable):
Summary lines{"commit":"f8b22edfb7f5","dirty":false,"env":{"APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"100:30"},"gpu":"AMD Radeon RX 9070 XT (RADV GFX1201)","driver":"radv Mesa 26.2.4-arch1.1","os":"Linux 7.2.9-arch1-1","resolution":"3840x2160","window":{"spec":"seconds 100:30","first_present":771,"ms":30041.458},"presents":216,"frame_ms":{"p50":130.2,"p90":161.713,"p99":275.775,"max":455.902},"gpu_busy_ms_per_present":78.23,"trace":"aps5-trace-f8b22edfb7f5-370363.json.gz"}
{"commit":"f8b22edfb7f5","dirty":true,"env":{"APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"100:30"},"gpu":"AMD Radeon RX 9070 XT (RADV GFX1201)","driver":"radv Mesa 26.2.4-arch1.1","os":"Linux 7.2.9-arch1-1","resolution":"3840x2160","window":{"spec":"seconds 100:30","first_present":1187,"ms":30077.514},"presents":321,"frame_ms":{"p50":84.548,"p90":115.084,"p99":123.446,"max":210.047},"gpu_busy_ms_per_present":48.711,"trace":"aps5-trace-f8b22edfb7f5-377486.json.gz"}
{"commit":"f8b22edfb7f5","dirty":false,"env":{"APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"100:30"},"gpu":"AMD Radeon RX 9070 XT (RADV GFX1201)","driver":"radv Mesa 26.2.4-arch1.1","os":"Linux 7.2.9-arch1-1","resolution":"3840x2160","window":{"spec":"seconds 100:30","first_present":1182,"ms":30102.816},"presents":325,"frame_ms":{"p50":87.85,"p90":113.641,"p99":120.253,"max":122.562},"gpu_busy_ms_per_present":48.443,"trace":"aps5-trace-f8b22edfb7f5-388013.json.gz"}
{"commit":"f8b22edfb7f5","dirty":true,"env":{"APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"100:30"},"gpu":"AMD Radeon RX 9070 XT (RADV GFX1201)","driver":"radv Mesa 26.2.4-arch1.1","os":"Linux 7.2.9-arch1-1","resolution":"3840x2160","window":{"spec":"seconds 100:30","first_present":934,"ms":30053.807},"presents":236,"frame_ms":{"p50":126.393,"p90":129.001,"p99":153.913,"max":155.756},"gpu_busy_ms_per_present":79.603,"trace":"aps5-trace-f8b22edfb7f5-384471.json.gz"}
{"commit":"f8b22edfb7f5","dirty":false,"env":{"APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"100:30"},"gpu":"AMD Radeon RX 9070 XT (RADV GFX1201)","driver":"radv Mesa 26.2.4-arch1.1","os":"Linux 7.2.9-arch1-1","resolution":"3840x2160","window":{"spec":"seconds 100:30","first_present":1032,"ms":30016.046},"presents":254,"frame_ms":{"p50":117.267,"p90":121.144,"p99":147.852,"max":152.264},"gpu_busy_ms_per_present":82.231,"trace":"aps5-trace-f8b22edfb7f5-395030.json.gz"}
{"commit":"f8b22edfb7f5","dirty":true,"env":{"APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"100:30"},"gpu":"AMD Radeon RX 9070 XT (RADV GFX1201)","driver":"radv Mesa 26.2.4-arch1.1","os":"Linux 7.2.9-arch1-1","resolution":"3840x2160","window":{"spec":"seconds 100:30","first_present":1115,"ms":30058.106},"presents":295,"frame_ms":{"p50":99.901,"p90":108.835,"p99":124.458,"max":136.9},"gpu_busy_ms_per_present":80.439,"trace":"aps5-trace-f8b22edfb7f5-391491.json.gz"}The traces are kept locally; I can attach any of them. AI-assisted: yes (Claude Code) |
What
Every host import lookup walks the lease to find the run of registry ranges around an address (
importRun): from the containing range out to both ends of the run, building a vector of the ranges each time. Kena: Bridge of Spirits (PPSA01802) looks runs up thousands of times per frame (HostImportFor,sameRangein the import refresh,importAllocation), and the walk is one of the largest parts of the draw-preparation time.The run bounds are now memoized per thread. The key is the lease snapshot (its range array and size), the index of the containing range and the import window. Before use, the memo is checked against the first and last range of the stored run, so a new lease or a changed registry misses it.
sameRangeand the whole-run lookup inimportAllocationcompare the bounds directly, without building the run.APS5_NO_RUN_MEMO=1turns the memo off.Tested
AMD Radeon RX 9070 XT (RADV GFX1201), Mesa 26.2.4, Arch Linux (kernel 7.2.9), Kena: Bridge of Spirits (PPSA01802).
mainf8b22ed, no input,APS5_TRACE_SECONDS=100:30, three rotated rounds. Comparable runs:main216 / 254 presents, this PR 236 / 295 (one run of each reached a lighter stretch at 48 ms GPU busy and is left out; summary lines in the review reply). An earlier batch had the memo alone at 239 / 235 / 248 againstmain191 / 227 / 208, about +15 %.agc_driver_graphicscase: a range registered next to an imported one, after which the next build's import must cover both.ctest -R '^agc_'six times with-j16: 629 of 630 pass each time;agc_driver_tessellationsegfaults onmaintoo.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code