Repository navigation
perf(agc): refuse uncached textures while the sampled cache's least recently used entry is still in use - #7640
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.
|
…ecently used entry is still in use Over budget but within a quarter over it, the sampled texture cache refused no use of a texture it does not hold, so a cyclic scan over a working set larger than the budget rotated the whole cache and hit almost never. The first use of a key in a present is now refused (used for its draw, never cached) when the least recently used entry was used in this or the previous present. A later use of the key is refused only when that entry was used in this present, so a texture used several times per present is still admitted on a later use. The refusal does not apply past the quarter-over ceiling, so a budget that falls still evicts. The test lowers the budget through OverrideCacheBudgetForTest instead of the environment. The debt entry records the unmeasured present window, that a texture used more than once still rotates the cache, and the one A-B-A measurement. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
ebeac30 to
8706cd8
Compare
|
This pull request is labeled |
|
Checked the admission change in Added one commit on your branch: the new Merged. |
What
When a frame uses more sampled textures than the sampled texture cache's budget,
admitTexturerefused only the first use of a texture in a present. Every later use of that texture evicted the cache's least recently used entry, even when the same present had just used that entry. A working set larger than the cache then turns over every frame: strict LRU over a repeating scan bigger than the cache gets almost no hits, and every eviction destroys a texture the next draw needs again.Ghost of Yōtei's loading phase uses about 33,000 textures (11–13 GiB) per frame against a sampled budget of about 5.4 GiB. On
mainthe cache evicted about 2.7M textures an hour there and passed over about 13M held entries.Now, while the cache is over its budget and within a quarter over it:
A refused texture is used for its draw and released, as before. So the cache keeps a stable subset of the working set instead of rotating through it. The +25% ceiling is checked before the refusal, so past it entries are evicted as before and a cache whose budget falls still trims.
OverrideCacheBudgetForTest(declared next toTextureCacheUsage) lets a test set the cache budget between inserts;forcedCacheBudgetchecks it before the one-timeAPS5_TEXTURE_CACHE_MIBread, and 0 clears it.Tests in
SampledCacheBudget.cpp:main0 of 80 lookups hit; the test requires at least a quarter of them to hit;Measured
Ghost of Yōtei (PPSA26344), RTX 4090 (driver 617.42), Windows 11, warm shader cache, 3600 s per run, the same save and pad input. Local integration tree:
main1c523bd plus 17 local commits (#6492 before it merged, a host-heap fallback chain, a pad-input hook and logging). A1 and A2 are that tree; B is A plus this PR's rule; the commit pushed here differs from the measured build only in the test seam and the debt entry. Counters are from the[texture-cache],[texture]and[resources] images tooklines after frame 620, where the loading phase starts.B reached 968 frames against 932 and 941, +10% frames after frame 620. Evictions fell 57% and passed-over entries 77%. The number of textures created is unchanged: the working set is still more than twice the budget, so the textures that do not fit are still created at each use. The gain comes from fewer evictions and less walking of the LRU list, and draw resource builds took 3% less time.
Budget and heap use
The placement lines print only when a device-local allocation is placed in host memory, so they show the heap at its fullest; the three runs are alike.
A stricter form that refused every use of an uncached texture in the present (run212) reached 962 frames with the same eviction and creation counts (1.18M evicted, 5.78M created), so the second-use exception kept here costs nothing measurable.
Technical debt
New entry "Scan-resistant sampled texture admission" in
docs/dev/debt/libSceAgcDriver.md:main;Tested
Windows 11 Pro 26200, RTX 4090, driver 617.42. This branch on
main376c040:agc_driver_sampled_cache_budget,agc_driver_sampled_cache_budget_memoryandagc_driver_sampled_cache_budget_without_storage_image_multisample.agc_driver_bda_devicefails withvkWaitForFences graphics: Vulkan result 2, alone too. It fails the same way withmain'sShaderResources.cpp,ShaderResources.hppandSampledCacheBudget.cppin this tree, so it is agc_driver_bda_device times out in vkWaitForFences since the BDA anchor lookup (#5859, d422c760c) #7584, not this change.scanTestsfails onmain(0 of 80 lookups hit);secondUseTestswould pass onmaintoo and guards the second-use admission kept here.Related
The remaining churn is capacity: about 4.5M uncached creations an hour. #6982 (drop the guest snapshot of large cached textures) and #6937 (sampled budget, snapshot reuse) touch the same cache; neither changes admission.
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