Skip to content

shader: cache the resolved raw-global table entry in registers - #3

Open
biosed wants to merge 3 commits into
switch2-native-basefrom
claude/gmem-entry-cache
Open

biosed wants to merge 3 commits into
switch2-native-basefrom
claude/gmem-entry-cache

Conversation

@biosed

@biosed biosed commented Nov 13, 2026

Copy link
Copy Markdown
Owner

On every raw global access the resolver checked the table entry it used last. That cached only the entry index, so a hit still loaded four map words for the range check and two more for the delta, all dependent on that index. This change keeps the chosen entry's start, end and delta words in a zero-initialised private array, one per helper kind. A hit then needs no table loads. A miss refills the cache from the hint or search path, as before.

Correctness

  • Vector accesses now check that their last byte is inside the cached entry before taking the hit path. The old last-index path skipped that check.
  • A refused address still reads zero.

Evidence (Ocarina of Time, M1 Pro, Honeykrisp G13, FSR1 tier 1)

In-run A/B of the whole 520-module task/mesh set: the host's DM_VK_MESH_B alternates sets every 600 frames on one route.

p50 p95 p99 ≤33.3 ms GPU p50
vector3 (switch2-native-base) 32.75 34.45 36.18 73.5% 26.24
+ entry cache 32.39 34.15 34.98 82.1% 25.99
  • GPU time was lower in all 5 adjacent pairs.
  • Material-pass producers, offline shaderdb: static instructions rose from 393k to 428k and spills from 329 to 442, because of the refill code. The executed hit path is shorter, which is what the A/B measures.
  • All 520 modules pass spirv-val --target-env vulkan1.3.
  • Screenshots render correctly in both arms.

Note: dmsh_spv_native.DONOR_SOURCE_SHA covers only Program.cs and the csproj, so this Ryujinx-side change doesn't alter the pin. Rebuilt sets should be recorded with the translator commit.

🤖 Generated with Claude Code

seedds and others added 3 commits November 13, 2026 18:04
A raw global access (an address traced to no storage buffer) resolved
its pool through the host's table on every access. The fast path kept
only the last entry index, so a hit still loaded four map words to
check the range and two more for the delta, all dependent on the index.

Each helper kind now keeps the chosen entry's six words (start, end,
delta) in a zero-initialised private array. A hit compares against
those values and adds the cached delta without loading the table. A
miss takes the hint or search as before and refills the cache. A
vector access also checks that its last byte is inside the cached
entry; the old last-index path skipped that check.

Ocarina of Time (0400486024DEC000), M1 Pro / Honeykrisp G13, FSR1
tier 1, in-run mesh-set A/B (host DM_VK_MESH_B, 600-frame phases):
- frame p50 32.75 -> 32.39 ms; p95 34.45 -> 34.15 ms;
  p99 36.18 -> 34.98 ms;
- frames within 33.3 ms 73.5% -> 82.1%;
- GPU -0.14 ms median, lower in all five adjacent pairs.

Material-pass producers (offline shaderdb): static instructions
393k -> 428k, spills 329 -> 442, because cache refill code is added.
The executed hit path is shorter. All 520 task/mesh modules pass
spirv-val --target-env vulkan1.3. Screenshots in both arms render
correctly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every raw helper resolves through the same immutable table, so one
six-word cache per shader is enough. A store after a load to the same
pool hits too, and only one zero-initialised array is live. The old
one-word last-index memory (AddRawLastEntryMemory) and its bindings are
no longer used, so they are removed.

The 520 Ocarina task/mesh modules are byte-identical to the per-kind
build measured in the PR. These shaders have one raw access kind, so
the in-run A/B result applies unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment and field placement only: the six-word cache comment replaces
the stale one-word last-index description and documents the vector
last-byte bound. Translator output is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants