Repository navigation
perf(shader): compile resource plan walks instead of interpreting them - #6095
Conversation
Castlevania and Diablo II on this PR: about +11% and +13% presents per second on LinuxSystem: Linux, Ryzen 9 5950X, RTX 3080 Ti (NVIDIA 615.71.09) ResultsSteady-state windows of 10 s, about 2 minutes in game.
Merge conflict with
|
cf6e640 to
7174e15
Compare
7174e15 to
5aeb788
Compare
|
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.
|
adriadam10
left a comment
There was a problem hiding this comment.
Thanks for the tape, the ops match SrtEvaluator.cpp and agc_shader_memory passes on the merge with main (Linux). One thing blocks it:
SrtTape::Runnever fillsruntime.userDataUse.materializeCapturesets it (Recompiler.cpp:1347) andResourceMaterializer.cpp:803passes the plan's ownmaterializationSources/cleanFlatSlots, so every capture takes the tape path. The Evaluator recordsasValue(SrtEvaluator.cpp:422),asBase(:205) andreads(:243); the tape records none, socapture.userDataUsestays empty and reachestagVariantRuns(DrawCapture.cpp:164).verifyTapehides it: it copies the runtime with the sameuserDataUsepointer, so the Evaluator fills it during verification andAPS5_VERIFY_SRT_TAPE=1reports 0 differences.verifySrtTapedoes not setuserDataUseeither.
To fix: record the same userDataUse in the tape (UserData nodes, and the base/read origin for raw reads), give verifyTape its own SrtUserDataUse and compare it (asValue, asBase, reads) with the one the tape produced, and make verifySrtTape run with userDataUse set and require equality. Mutating the new check (dropping the asValue update) should make it fail.
Smaller notes: the standard "revert the non-test files" negative can't build because CMakeLists.txt lists SrtTape.cpp; I mutated the tape's branch selection by hand and agc_shader_memory_tests fails, so that part is covered. The title FPS did not move in your own measurement (10.52 vs 10.39), so the gain is the ~1.3 ms/frame walk time; please say so in the description. #6946 also edits ResourcePlan.hpp and the IrResourcePlan size assert in ShaderDiskCache.cpp, so whichever lands second needs a rebase.
5aeb788 to
acee01a
Compare
|
Thanks, that was a real gap. The user-data use came with #4943 after this PR's last rebase, and the tape never recorded it. Fixed in acee01a:
Rebased onto db7176f. The full suite passes 1347 of 1349: the misaligned test is not built with MinGW, and |
Stale: the requested userDataUse change is in place on acee01a (checked while @adriadam10 is away).
What
Every capture walks its resource plan's runtime sources (
SrtWalker::EvaluateRuntimeSources): the descriptor dwords, the flat SRT slots and the control-flow conditions. Each of these is an IR expression that theEvaluatorinterprets value by value. On the S2 page of Sonic Origins Plus's main menu, the walk cost the queue worker 3.58 samples per frame (APS5 sampler, 15 s), about 8% of its time. That was before #1193, which made the interpretation itself cheaper: values are memoized in a per-thread array instead of a hash table, and the walk reads a compact copy of the plan.A plan's walk is now compiled once into a flat node array, one node per IR value and context, and run on every capture. The node array (
SrtTape) is kept with the plan. The tape keeps the Evaluator's results and reads: the clean and read-first-lane contexts, lazy evaluation, the read trace, image activity, and a constant read past its V# reading 0. It also records the user-data use that the Evaluator records for draw relocation (#4943):asValue: a user-data word read as a value;asBase: a word that a raw read takes directly as its base address, which does not count as a value;reads: each raw read's address, together with that word.A walk the tape hands back to the Evaluator leaves no record behind.
The tape hands a walk to the Evaluator whenever it cannot finish it exactly as the Evaluator would. That covers a read through a null user-data root, an inaccessible word, or a failed operation.
APS5_NO_SRT_TAPE=1evaluates with the Evaluator only.APS5_VERIFY_SRT_TAPE=1runs both and reports any difference. The Evaluator gets its own user-data use there, which is compared with the tape's.IrResourcePlanguards move to 24 fields and, on Linux with libstdc++, 728 bytes.agc_shader_memory(verifySrtTape) walks three cases through both the tape and the Evaluator: the guarded-image program in four (T#, branch) states, a null SRT pointer, and a constant read past its V#. It requires every output to match, the user-data use included, and requires the guarded program's walk to report a user-data use. A tape that leaves out image activity, or does not mark a word it reads as a value, fails it.APS5_VERIFY_SRT_TAPE=1compared 1,000,000 walks of the S2 page with the Evaluator and found 0 differences. That run predates the user-data use, which main added with perf(agc): find cached draws across moved user-data pointers #4943 after this PR's previous rebase.Before #1193,
EvaluateRuntimeSourcesfell from 3.58 to 1.68 samples per frame, and the Evaluator's own time from 2.95 to 0. Against today's compact walk, the tape cuts the walk's time per capture from 4.70 to 2.84 us (see Tested). The title FPS does not move with it (10.52 against 10.39), so the gain is the walk's own time, about 1.3 ms per frame.Overlapping PRs:
ResourcePlan.hppand theIrResourcePlansize assert inShaderDiskCache.cpp.Tested
Windows 11 (10.0.26300), WinLibs GCC 15.2.0 (UCRT), Release, NVIDIA GeForce RTX 2080 Ti, driver 617.14.
agc_shader_memory(withverifySrtTape),agc_shader_disk_cache,agc_shader_bindlessandagc_shader_srt_read_patching.agc_driver_gpu_indirect_arguments_misaligned_writer_aheadis not run: main itself does not compile it with MinGW.select_testsfails in its setup on Windows without the symlink privilege (WinError 1314fromsymlink_to), as on main.verifySrtTapefails when the tape'sasValueupdate is removed.APS5_VERIFY_SRT_TAPE=1,agc_shader_memory's walks report 0 differences, the user-data use included.APS5_TRACE_SECONDS=200:15on the same machine in one session, caches warm. Traces attached.The FPS shown in the title went from 7.53 to 7.96 (median of six readings).
These numbers predate #1193: their baseline interprets with the hash-table Evaluator. Against today's walk I measured the walk itself:
APS5_NO_SRT_TAPE=1(main's compact walk). Change: the tape.APS5_PROFILE_DRAW=1, its[capture]line (printed every 10 s).The menu makes about 7,300 captures per second, so that is about 1.3 ms per frame at its 10.5 FPS. The title FPS does not show a change of that size: 10.52 with the compact walk, 10.39 with the tape (median of 12 readings, one run each).
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)Traces and summary lines (baseline f7a41ad, this change b593e36):
tape-traces.zip