Repository navigation
Reuse a captured page for the rest of its uniform words - #315
Closed
SkippySteve wants to merge 1 commit into
Closed
SkippySteve wants to merge 1 commit into
SkippySteve wants to merge 1 commit into
Conversation
Every word of a uniform buffer took the pool lock to ask whether that page was in the submit-time capture. The following words are the same page, until a stamp or the next capture.
This was referenced Nov 7, 2026
Owner
valonsodev
added a commit
to valonsodev/Hookshot
that referenced
this pull request
Nov 9, 2026
memory_read_as_submitted kept the last page it read (NotRexed#315) so the next read of that page skipped pools_mu. A handle program reads a uniform word on one page and a storage buffer word on another, so with one page kept those reads took turns missing: each took pools_mu and copied the whole 4 KB page for its 4 bytes. In Hyrule Castle Town, on a test route, that was about a quarter of the replay thread's draw time (program_for's answer handles). The answers are kept per page now, 32 a thread, by page number; a page is reused under the same rule as before (same page, page generation and capture view). Assisted-by: Claude Opus 5.5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
valonsodev
added a commit
to valonsodev/Hookshot
that referenced
this pull request
Nov 10, 2026
memory_read_as_submitted kept the last page it read (NotRexed#315) so the next read of that page skipped pools_mu. A handle program reads a uniform word on one page and a storage buffer word on another, so with one page kept those reads took turns missing: each took pools_mu and copied the whole 4 KB page for its 4 bytes. In Hyrule Castle Town, on a test route, that was about a quarter of the replay thread's draw time (program_for's answer handles). The answers are kept per page now, 32 a thread, by page number; a page is reused under the same rule as before (same page, page generation and capture view). Assisted-by: Claude Opus 5.5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
valonsodev
added a commit
to valonsodev/Hookshot
that referenced
this pull request
Nov 10, 2026
…opy kept a thread memory_read_as_submitted kept, for a page a capture holds, a 4 KB copy of it a thread (NotRexed#315), and the 32 kept pages (the commit before) made that 128 KB of TLS a thread. A read of a captured page now copies the words it asks for from the capture under pools_mu, as a read that misses already did; the 32 slots keep only "in no capture", 24 bytes each. On NVIDIA Linux the 4 KB copies were a third of the replay's thread in Kokiri Forest (djs5008's measurements on NotRexed#1375). Where the copy is cheap it still cost more than the extra lock: OoT's Market on a test route, Linux, RTX 3060 Ti (cached host memory, 0.3 us a 4 KB read), only hookshot_vk.so swapped, 4 rounds alternating after a warm-up (one of the first's runs hung at boot waiting on a GPU fence, as runs before this change did too): fps (median) replay thread (Presentation Thread) before (one commit) 32.96 66.8 % after 35.48 60.9 % Every run after (34.1-35.8) was above every run before (32.0-33.5). Reads that went to the captures rose from ~0.3 to ~1.0 million a run, each a few bytes under pools_mu. Co-authored-by: djs5008 <35700921+djs5008@users.noreply.github.com> Assisted-by: Claude Opus 5.5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
valonsodev
added a commit
to valonsodev/Hookshot
that referenced
this pull request
Nov 10, 2026
memory_read_as_submitted kept the last page it read (NotRexed#315) so the next read of that page skipped pools_mu. A handle program reads a uniform word on one page and a storage buffer word on another, so with one page kept those reads took turns missing: each took pools_mu and copied the whole 4 KB page for its 4 bytes. In Hyrule Castle Town, on a test route, that was about a quarter of the replay thread's draw time (program_for's answer handles). The answers are kept per page now, 32 a thread, by page number; a page is reused under the same rule as before (same page, page generation and capture view). Assisted-by: Claude Opus 5.5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
valonsodev
added a commit
to valonsodev/Hookshot
that referenced
this pull request
Nov 10, 2026
…opy kept a thread memory_read_as_submitted kept, for a page a capture holds, a 4 KB copy of it a thread (NotRexed#315), and the 32 kept pages (the commit before) made that 128 KB of TLS a thread. A read of a captured page now copies the words it asks for from the capture under pools_mu, as a read that misses already did; the 32 slots keep only "in no capture", 24 bytes each. On NVIDIA Linux the 4 KB copies were a third of the replay's thread in Kokiri Forest (djs5008's measurements on NotRexed#1375). Where the copy is cheap it still cost more than the extra lock: OoT's Market on a test route, Linux, RTX 3060 Ti (cached host memory, 0.3 us a 4 KB read), only hookshot_vk.so swapped, 4 rounds alternating after a warm-up (one of the first's runs hung at boot waiting on a GPU fence, as runs before this change did too): fps (median) replay thread (Presentation Thread) before (one commit) 32.96 66.8 % after 35.48 60.9 % Every run after (34.1-35.8) was above every run before (32.0-33.5). Reads that went to the captures rose from ~0.3 to ~1.0 million a run, each a few bytes under pools_mu. Co-authored-by: djs5008 <35700921+djs5008@users.noreply.github.com> Assisted-by: Claude Opus 5.5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
memory_read_as_submittedtook the pool lock on every word of guest memory the replay reads (uniform and storage descriptors). It then checked whether that 4 KB page was in a capture. The next words of the same buffer are the same page.cap_view_genchanges. A page stamp, the written-page collection, and taking a capture all bump that generation, so a newer write is not served from the old copy.Test plan
python -I -B tests/test_submitted_page.pypasses: a page is reused only when the page, its write generation, and the capture generation all match, andmemory_read_as_submittedchecks that beforepools_mucap_view_bump. Removing the stamp's bump fails the test