Skip to content

perf(shader): skip unchanged memory epoch propagation - #13423

Merged
adriadam10 merged 2 commits into
boykopovar:mainfrom
Filip722:perf/shader-clean-memory-epochs-20261030
Oct 30, 2026
Merged

adriadam10 merged 2 commits into
boykopovar:mainfrom
Filip722:perf/shader-clean-memory-epochs-20261030

Conversation

@Filip722

Copy link
Copy Markdown
Contributor

What

RVE propagates ReadConst memory epochs to a fixed point even when the existing scan finds no relevant memory clobbers. Every reachable block then has the same initial epoch, so those sweeps repeat work during shader translation.

  • Initialize that known result directly when the scan finds no clobber.
  • Keep the existing propagation, dominance and reachability handling for clobbered programs.
  • Cover a clean loop in the existing fixture alongside its branch, backedge and nested-loop store cases.

Tested

Debian 13, GCC 15.2 Release, Ryzen 5 7640HS, AMD Radeon 760M / RADV Mesa 25.0.7-2+deb13u1. The RVE fixture, including the new case, passes on refreshed main b1b5353cfcee and candidate a08b7073b9fa. The same three windowless GPU fixtures (agc_driver_buffer_descriptor_runtime, agc_driver_buffer_unaligned_base, agc_driver_scalar_wide_loads) pass on both with Vulkan required, shader cache disabled and Khronos validation enabled. Verbose logs confirm actual Radeon execution and validation-layer insertion, with no VUID errors, missing-layer warnings or skips. These are local results.

Deterministic instrumentation of the reused fixture finds 17 of 23 invocations skip two dataflow sweeps; the six clobbered invocations retain identical sweep, predecessor-visit and replacement counts. All replacement counts agree. The emitted 5,548-byte synthetic SPIR-V module is byte-identical. This demonstrates less CPU bookkeeping, not an elapsed compilation measurement or a native shader-instruction reduction.

Verified timing evidence contains all four original traces, summaries, digests, protocol and provenance hashes. Gameplay was captured on pinned main da026c70655a and candidate bcb0a7f8f46a before the upstream refresh. The respective RVE sources are byte-identical through the merge; the same focused hardware tests and work/output comparison were rerun on the refreshed revisions, as recorded in the bundle. Sons of Sparta (PPSA28997 01.008.001), restored camp, 1920x1080 / focused 1152x648 Wayland client, mailbox: two warmed prospective pairs in A1/B1/B2/A2 order, no exclusions. Both arms were warmed through the complete later 25:12-second window. All 59 loaded PRX hashes, save, scene, focus and cache checks pass; only AgcDriver differs between runtime sets. The identical private clock/screenshot observer is attached in the evidence and stays out of this commit; screenshots occur outside timing, and summary dirty=true records that observer.

Mean gameplay is effectively neutral: 21.52218 to 21.52946 FPS (observed +0.034%; pairs +0.023% and +0.045%), GPU busy 43.2485 to 43.2300 ms/present. This warmed scene does not measure cold shader-compilation latency or establish a significant/general gameplay speedup.

{"commit":"da026c70655a","dirty":true,"env":{"APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"25:12"},"gpu":"AMD Radeon 760M (RADV PHOENIX)","driver":"radv Mesa 25.0.7-2+deb13u1","os":"Linux 7.2.12-x64v3-xanmod1","cpu":"AMD Ryzen 5 7640HS w/ Radeon 760M Graphics","cpu_threads":12,"memory_mib":23820,"title_id":"PPSA28997","title":"God of War Sons of Sparta","content_version":"01.008.001","resolution":"1920x1080","window":{"spec":"seconds 25:12","first_present":576,"ms":12045.478},"presents":259,"frame_ms":{"p50":46.446,"p90":47.023,"p99":48.179,"max":48.272},"gpu_busy_ms_per_present":43.225,"worker_busy_pct":{"queue worker 0x0":78.723},"top_phases_ms_per_frame":{"Driver.Packet":36.482,"Driver.Packet.draw":33.834,"Driver.Draw":33.795,"Driver.Draw.draw_enqueued":29.801,"Recorder.Sync":28.561,"VideoOut.Flip":9.194,"Driver.Present":9.157,"VideoOut.Flip.present":9.153},"trace_dropped":false,"trace":"aps5-trace-da026c70655a-3652985.json.gz"}
{"commit":"bcb0a7f8f46a","dirty":true,"env":{"APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"25:12"},"gpu":"AMD Radeon 760M (RADV PHOENIX)","driver":"radv Mesa 25.0.7-2+deb13u1","os":"Linux 7.2.12-x64v3-xanmod1","cpu":"AMD Ryzen 5 7640HS w/ Radeon 760M Graphics","cpu_threads":12,"memory_mib":23820,"title_id":"PPSA28997","title":"God of War Sons of Sparta","content_version":"01.008.001","resolution":"1920x1080","window":{"spec":"seconds 25:12","first_present":520,"ms":12042.762},"presents":259,"frame_ms":{"p50":46.428,"p90":46.964,"p99":48.322,"max":48.650},"gpu_busy_ms_per_present":43.220,"worker_busy_pct":{"queue worker 0x0":78.683},"top_phases_ms_per_frame":{"Driver.Packet":36.445,"Driver.Packet.draw":33.851,"Driver.Draw":33.811,"Driver.Draw.draw_enqueued":30.044,"Recorder.Sync":28.895,"VideoOut.Flip":9.144,"Driver.Present":9.130,"VideoOut.Flip.present":9.102},"trace_dropped":false,"trace":"aps5-trace-bcb0a7f8f46a-3653852.json.gz"}
{"commit":"bcb0a7f8f46a","dirty":true,"env":{"APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"25:12"},"gpu":"AMD Radeon 760M (RADV PHOENIX)","driver":"radv Mesa 25.0.7-2+deb13u1","os":"Linux 7.2.12-x64v3-xanmod1","cpu":"AMD Ryzen 5 7640HS w/ Radeon 760M Graphics","cpu_threads":12,"memory_mib":23820,"title_id":"PPSA28997","title":"God of War Sons of Sparta","content_version":"01.008.001","resolution":"1920x1080","window":{"spec":"seconds 25:12","first_present":562,"ms":12017.323},"presents":259,"frame_ms":{"p50":46.322,"p90":46.888,"p99":48.150,"max":48.323},"gpu_busy_ms_per_present":43.240,"worker_busy_pct":{"queue worker 0x0":78.673},"top_phases_ms_per_frame":{"Driver.Packet":36.373,"Driver.Packet.draw":33.805,"Driver.Draw":33.765,"Driver.Draw.draw_enqueued":29.998,"Recorder.Sync":28.895,"VideoOut.Flip":9.183,"Driver.Present":9.172,"VideoOut.Flip.present":9.145},"trace_dropped":false,"trace":"aps5-trace-bcb0a7f8f46a-3654823.json.gz"}
{"commit":"da026c70655a","dirty":true,"env":{"APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"25:12"},"gpu":"AMD Radeon 760M (RADV PHOENIX)","driver":"radv Mesa 25.0.7-2+deb13u1","os":"Linux 7.2.12-x64v3-xanmod1","cpu":"AMD Ryzen 5 7640HS w/ Radeon 760M Graphics","cpu_threads":12,"memory_mib":23820,"title_id":"PPSA28997","title":"God of War Sons of Sparta","content_version":"01.008.001","resolution":"1920x1080","window":{"spec":"seconds 25:12","first_present":591,"ms":12022.733},"presents":259,"frame_ms":{"p50":46.369,"p90":46.913,"p99":48.058,"max":48.418},"gpu_busy_ms_per_present":43.272,"worker_busy_pct":{"queue worker 0x0":78.688},"top_phases_ms_per_frame":{"Driver.Packet":36.396,"Driver.Packet.draw":33.804,"Driver.Draw":33.761,"Driver.Draw.draw_enqueued":30.023,"Recorder.Sync":28.716,"VideoOut.Flip":9.202,"Driver.Present":9.166,"VideoOut.Flip.present":9.163},"trace_dropped":false,"trace":"aps5-trace-da026c70655a-3655674.json.gz"}

The full overlap scan found two unmergeable shared-file proposals, reviewed manually: #12324 updates the metadata exec reference; #12548 adds NanPropagateF32 to the recomputable opcode list. Neither changes memory-epoch propagation or this fixture case.

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
  • Fixes: none
  • Unblocks: none
  • GPUs tested: AMD Radeon 760M (RADV PHOENIX), RADV Mesa 25.0.7-2+deb13u1, Debian 13 / Linux 7.2.12-x64v3-xanmod1
  • AI-assisted: yes

@github-actions github-actions Bot added the perf Performance change label Oct 30, 2026
@github-actions

Copy link
Copy Markdown

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 12324 core/shader/recompiler/Optimization/src/RedundantValueEliminator.cpp
PR 12548 core/shader/recompiler/Optimization/src/RedundantValueEliminator.cpp

@maskym

maskym commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

Windows + NVIDIA result for head a08b7073b9, merged into main ed1e0ed08f together with the open PR #13432 (both merged cleanly, so the run is a joint one; the PR's Tested section names no Windows run). Correctness only; no title trace here, so nothing below speaks to the speed claim.

Host: Windows 11 26300, Intel i7-12700K, NVIDIA GeForce RTX 2070 SUPER, WinLibs GCC 15.2.0 (x86_64-ucrt-posix-seh, r6), Release, BUILD_TESTING=ON, Ninja. Build clean.

Same machine, both trees, with ANYPS5_REQUIRE_VULKAN=1, ANYPS5_NO_SHADER_CACHE=1, VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation (Khronos VVL 1.4.366) and ctest --test-dir build -R '^(agc|guest_video_out|video_out)' --parallel 4 -V:

Tree Result Layer inserted was not found but was requested Distinct VUID-
main ed1e0ed08f 1211/1211 1053 0 VkPipelineColorBlendStateCreateInfo-pAttachments-00605 ×18 (#11990)
PR tree 1211/1211 1053 0 the same, ×18

No new validation errors. agc_redundant_value_elimination, the test this PR extends, passes on both trees (0.26 s), and every shader test in the set passes. Not run on a PS5.

AI-assisted: yes (Claude Code), the runs and the numbers above are from this machine.

@adriadam10 adriadam10 self-assigned this Oct 30, 2026
@adriadam10
adriadam10 merged commit 8ed8812 into boykopovar:main Oct 30, 2026
24 of 25 checks passed
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the new hasClobber shortcut in RedundantValueEliminator.cpp: all blocks are reachable (unreachable ones throw earlier), so with no clobber every entry epoch is 1 and the skipped fixed point gives the same result; clobbered programs keep the existing path. The new loop case covers it. Windows + NVIDIA run by @maskym shows no new validation errors; the one red check (relinker windows, check_main_sync timeouts) is unrelated; merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

perf Performance change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants