Reuse a guest pool's span without taking the pool lock #310

Closed
SkippySteve wants to merge 1 commit from fix/pool-span-cache into main
SkippySteve commented 2026-11-07 20:09:28 +00:00 (Migrated from github.com)

Summary

  • gpu_pool_end and gpu_pool_start took the pool lock on every call. Storage-buffer tables ask this once per entry, and the entries of one table sit in one pool. The same locked lookup, before buffer binds cached it, was about 8% of replay time.
  • A thread keeps the last guest-pool span and reuses it while guest_pools_gen is unchanged. memory_sync bumps that generation when it replaces the table, so a refreshed pool list is not served from the old span. RX_VK_POOL_END_IMPORTED still skips the game-pool span and takes the lock.

Test plan

  • python -I -B tests/test_pool_span.py passes: a span covers its interior only for the generation it was cached from, both queries check the cache before ParLock, and memory_sync bumps the generation at the swap
  • Dropping the generation bump fails the test, and moving the cache check to after the lock fails it
  • CI: "Check a pool span is reused without the lock"
## Summary - `gpu_pool_end` and `gpu_pool_start` took the pool lock on every call. Storage-buffer tables ask this once per entry, and the entries of one table sit in one pool. The same locked lookup, before buffer binds cached it, was about 8% of replay time. - A thread keeps the last guest-pool span and reuses it while `guest_pools_gen` is unchanged. `memory_sync` bumps that generation when it replaces the table, so a refreshed pool list is not served from the old span. `RX_VK_POOL_END_IMPORTED` still skips the game-pool span and takes the lock. ## Test plan - [x] `python -I -B tests/test_pool_span.py` passes: a span covers its interior only for the generation it was cached from, both queries check the cache before `ParLock`, and `memory_sync` bumps the generation at the swap - [x] Dropping the generation bump fails the test, and moving the cache check to after the lock fails it - [ ] CI: "Check a pool span is reused without the lock"
NotRexed commented 2026-11-07 20:18:29 +00:00 (Migrated from github.com)

Thanks! This one changes timing/locking on the replay's hot path, so I'll measure it (fps and frame times in Kokiri, plus a few boots) before merging. The two clock-gating PRs (#306, #308) are merged.

Thanks! This one changes timing/locking on the replay's hot path, so I'll measure it (fps and frame times in Kokiri, plus a few boots) before merging. The two clock-gating PRs (#306, #308) are merged.
NotRexed commented 2026-11-07 20:59:22 +00:00 (Migrated from github.com)

Thanks! Measured together with the other replay PRs (replay 27 -> 24-25 ms a frame, fps 23 -> 26 in Kokiri) and applied by hand (conflicts only in the CI workflow; #310 and #315 needed one declaration moved), pushed in 40c3f85.

Thanks! Measured together with the other replay PRs (replay 27 -> 24-25 ms a frame, fps 23 -> 26 in Kokiri) and applied by hand (conflicts only in the CI workflow; #310 and #315 needed one declaration moved), pushed in 40c3f85.
Commenting is not possible because the repository is archived.
No description provided.