Skip to content

fix(agc): remember the differing statistics' value sets by hash - #8263

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
milescoviello:fix/profile-differing-value-set-hashes
Oct 21, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
milescoviello:fix/profile-differing-value-set-hashes

Conversation

@milescoviello

@milescoviello milescoviello commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

What

With APS5_PROFILE_DRAW, Driver::classifyDiffering sorts each dispatch-cache miss whose captured SRT words differ from the entry's. To count how often a miss brings back one of the last three value sets of its key, it copied the entry's runs and words into a ring of three per dispatch key, for up to 16384 keys (priorValueSets is cleared only when it holds more keys than the dispatch cache has entries). The ring is only compared for equality, so it now keeps a 64-bit FNV-1a hash of each value set (the runs and the words, each with its size) instead of a copy. The counter reports the same numbers. A hash collision could add a match with a chance of about one in 2^64.

Why

Ghost of Tsushima (PPSA02225) captures more than 1 MiB of SRT words per compute dispatch. I took a profiled run at 16 GiB on main-based libraries (97f525ba19 plus #8213 and #6982; DispatchCacheStatistics.cpp and priorValueSets are the same as on main). Joining the live allocations 274 s in with their allocation stacks showed 352 MiB in these copies: 134 + 90 MiB from the vector copies in classifyDiffering, and 77 + 51 MiB in the std::deque insertion it calls. Profiled runs are how titles are measured for pull requests, so the copies took memory from the run being measured. In this title they used memory that a run without profiling has.

Tested

Ubuntu 24.04 (Linux 6.8), GCC 13.3, NVIDIA RTX 4070 Ti, driver 595.99.02.

  • New test agc_driver_dispatch_differing_value_sets. It uses one dispatch key, a kernel that loads its output V# through the SRT pointer, and an SRT that alternates between two value sets (the V#'s record count, 64 and 65). APS5_DISPATCH_VARIANTS=1 makes every dispatch after the first a differing miss. The test checks that the four misses are classified and that the three bringing back a value set seen before match it. It reads the counters through the new Driver::DispatchCacheCounters(), the dispatch counterpart of DrawCacheCounters(). The counters are reset by the 10 s profile report, so the test sums deltas across a reset.
    • main with only the accessor and the test: 4 classified, 3 matched, 3 of 3 runs. This PR: the same, 3 of 3. So the statistic is unchanged.
    • With the remembered hash deliberately broken (valueSet(old) + 1), it fails with 0 matched.
  • Khronos validation layer (LunarG SDK 1.4.363), NVIDIA RTX 4070 Ti (595.99.02), Ubuntu 24.04: VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ANYPS5_NO_SHADER_CACHE=1 ANYPS5_REQUIRE_VULKAN=1 ctest -R '^agc_driver_(dispatch|image_table|compute|address_passes|draw_cache)' -V. main 1edbe4b passed 20 of 20, and this change at 8d99dad5ba (the same diff before the rebase onto 1edbe4b) passed 21 of 21, the new test included. Neither log reports the layer missing, and neither has a VUID- error. After the rebase the new test passes 3 of 3.
  • tools/check_conventions.py --base upstream/main passes. tools/pr_overlap.py only lists open PRs it couldn't compare, on Driver.hpp and DispatchCacheStatistics.cpp. Of those, feat(agc): look up table images at run time through a device image table on the GPU heap (APS5_GPU_PATH) #7642 is the one that edits the statistics file, and it only changes the report line.

Not tested: a profiled title run with this change. On this machine, Ghost of Tsushima at 16 GiB now stops at the host memory guard (126 s and 151 s today) before the point measured above.

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: NVIDIA GeForce RTX 4070 Ti, driver 595.99.02, Ubuntu 24.04
  • AI-assisted: yes (Claude Code)

🤖 Generated with Claude Code

With APS5_PROFILE_DRAW, every dispatch that misses because its captured
SRT words differ copies the entry's runs and words into a ring of the
last three value sets per dispatch key, for up to 16384 keys. The ring
only answers whether a new value set equals one of them, so it now keeps
a 64-bit hash of each set instead of a copy.

Ghost of Tsushima captures SRT words of more than 1 MiB per compute
dispatch, and a profiled run held 352 MiB of these copies 274 s in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the agc libSceAgc* label Oct 20, 2026
@github-actions

github-actions Bot commented Oct 20, 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 6188 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp L74

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 5404 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 5431 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 5609 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 5925 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 6292 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 6501 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 6539 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 6615 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 6804 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 6946 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 6947 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 7446 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 7642 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Dispatch/DispatchCacheStatistics.cpp
PR 7644 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp

@oneandonlydean
oneandonlydean merged commit e0e57a3 into boykopovar:main Oct 21, 2026
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc*

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants