Repository navigation
fix(shader): key the device's capabilities and extensions by a digest - #10438
Conversation
Every recompile cache key appended the target's capability list and each SPIR-V extension name one byte per 64-bit word, so on a device that enables a few dozen extensions most of every key was the same device description: built and compared on every dispatch and draw, and kept in every in-memory key and disk cache entry. The two lists now enter the key as a 128-bit digest over the capabilities and the length and bytes of each extension name, eight bytes per step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
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.
|
|
A Ghost of Tsushima (PPSA02225) result, with this change and the release of unused specialized modules (#10473) together on the stack the title needs to reach its opening. Same seed pipeline cache, 20 GB cap, Linux, RTX 4070 Ti. Against the same stack without the two changes, the title was killed by the cap at 1,260 s instead of 633 s. AI-assisted: yes (Claude Code) |
|
A caveat on the Ghost of Tsushima comparison above, from a third run. This one had both changes, plus a third that is inert on a fresh cache version, at a 19 GB cap instead of 20 GB. It was killed by the cap at 913 s. So the run-to-run spread in this title's opening is about as large as the per-minute difference I reported, and those numbers shouldn't be read as the saving. The run lengths point the same way: 633 s without the changes, 1,260 s and 913 s with them, the last at the lower cap. The count of interned modules held only by the module caches (323 to 345 MiB at 10 to 12 min) is a direct count, not a comparison. AI-assisted: yes (Claude Code) |
|
Checked that the key is never decoded (only compared), that every other |
MarcZX10
left a comment
There was a problem hiding this comment.
Reviewed exact head d7d9747e7d9aae3375846c52f4814c3b80d2cb39.
The cache key now replaces the variable-length capability/extension payload with two fixed 64-bit digest words while including list counts, capability values, extension lengths, and extension bytes. Other target fields retain their existing key representation. The test checks storage-independent equality, changed extension bytes, byte movement between names, added capabilities, and bounded key size for 40 extensions.
Local current-main merge-tree is clean; conventions and diff-check pass. Hosted eligibility, intake, labels, report, and conventions pass; hosted build/product jobs are skipped. The author reports focused Vulkan/validation-layer and Windows VM runs; I did not reproduce GPU/title measurements locally. No blocking findings on this head.
What
RecompileCacheKeyputs the wholeSpirvTargetinto every recompile cache key. Two of its fields are lists: the device's SPIR-V capabilities, and the SPIR-V extension names, which go in one byte per 64-bit word. On a device that enables a dozen extensions, that is about 350 words of the same device description in every key. The key is built and compared on every dispatch and draw, kept in memory by every prepared handle and cache entry, and written into every disk cache entry.SPV_EXT_demote_to_helper_invocation...SPV_KHR_terminate_invocation), their lengths and the capability list.RecompileCacheKey::appendholds about 380 MiB of live memory. That title is killed by its 20 GB memory cap in its opening, so this is memory it needs back.How
append(key, SpirvTarget)now adds the two lists as one 128-bit digest instead of word by word. The digest mixes the capability count and values, then each extension's length and its bytes eight at a time, through two independent 64-bit multiply-xor chains. Every otherSpirvTargetfield is appended as before. The disk cache source version changes with the recompiler sources, so old entries aren't misread.Tested
Ubuntu 26.04.1, GCC 15.2, Release, RTX 4070 Ti, NVIDIA 615.71.09. The commit was tested as
6fbdaa9d69onmainf3456a4 and is unchanged (git range-diff) on the current headd7d9747e7d, rebased ontomain3b23d18.verifyTargetFeatureKeyinagc_shader_memory. Equal lists in other storage give the same key. A different last byte of an extension name, a byte moved between two names, or an added capability each give a different key. A key built with 40 extension names is no longer than one built with 2. With only the test onmain,agc_shader_memoryfails 3 of 3 withtarget feature key: the key grows with the device's extension names; with the change it passes 3 of 3.^agc_shader_memory$|^agc_spirv_module$|^agc_shader_|shader_disk_cache|^agc_driver_graphics$|pipeline_journalpass 3 of 3 onmain9d4fb4f and on6fbdaa9d69.VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ANYPS5_NO_SHADER_CACHE=1 ANYPS5_REQUIRE_VULKAN=1on the 5 tests matching^agc_shader_memory$|^agc_spirv_module$|^agc_shader_disk_cache$|^agc_driver_graphics$|^agc_driver_pipeline_journal$.main9d4fb4f: 5 of 5 pass;6fbdaa9d69: 5 of 5 pass. Neither log reports the layer missing, and neither has a VUID.mainat the merge base (f3456a4) and on6fbdaa9d69.Not checked by me: AMD, Intel, macOS, and a title run measuring the saving (Ghost of Tsushima needs more free host memory than this machine has right now).
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