Skip to content

rex3-jit: prioritise hot shader compiles over a full queue - #319

Merged
techomancer merged 1 commit into
techomancer:mainfrom
irix7:pr/rex3-compile-queue
Oct 25, 2026
Merged

techomancer merged 1 commit into
techomancer:mainfrom
irix7:pr/rex3-compile-queue

Conversation

@belikh

@belikh belikh commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

The async REX3 shader compiler takes work from one bounded channel (256 slots). A full channel drops the request so the GFIFO consumer never blocks, but it cannot tell a warm-up/prefetch shape from the one the guest is drawing right now. A boot-time profile flood can fill every slot and starve the live draw, which then runs on the interpreter until the backlog drains — 30-second waits in graphics tests.

  • Split the work into two lanes. The cold lane (warm-up, prefetch) keeps the 256-request bound and stays best-effort: a rejected request drops its Queued marker so a later draw retries.
  • The hot lane is the draw path. It is unbounded, never rejected, and the worker drains it before the cold lane, so live draw work cannot be starved by prefetch.
  • The worker parks on a condvar rather than spinning. The queue carries no Cranelift types, so the lane behaviour (including a hot request jumping a full cold queue) is unit-tested without starting a compiler.
  • clanker/rex3/rex-jit-queue-retry.md records the drop-and-retry contract.

Tests: cargo test --workspace on upstream/main — 1332 passed, 0 failed.

The async shader compiler took work from one bounded SyncSender. A full channel dropped the request so the GFIFO consumer never blocked, but it made no distinction between a warm-up/prefetch shape and one the guest is drawing now: a boot-time profile flood could fill all 256 slots and starve the live draw, which then ran on the interpreter until the backlog drained.

Give the compiler two lanes: a bounded cold lane for warm-up and prefetch, best-effort and retried later if rejected, and a hot lane for the draw path that is never rejected and is drained first. The worker parks on a condvar instead of spinning. The queue carries no Cranelift types, so its behaviour is unit-tested without a compiler.
@belikh

belikh commented Oct 25, 2026

Copy link
Copy Markdown
Contributor Author

Evidence behind the change (the fork now requires this for every upstream PR):

  • Reproduction. A 263-entry warm-up profile fills the old single 256-slot channel. The next live draw calls request_compile; try_send fails, the Queued marker is removed, and that draw runs on the interpreter until the backlog drains. On the fork this showed up as 30-second waits in graphics tests with a populated ~/.iris/rex-jit-profile.bin. With the two lanes, the same profile's live draw is admitted to the hot lane and the cold backlog drains behind it.
  • Tests in this PR. hot_draw_request_jumps_a_full_cold_queue fills the cold lane and requires a hot draw request to be admitted and drained first; hot_request_is_admitted_ahead_of_a_full_cold_queue checks the admission order at the queue level without starting a compiler.
  • Contract. clanker/rex3/rex-jit-queue-retry.md (updated here) records the drop-and-retry rule for a rejected cold request.

If you would prefer the 263-entry profile as an in-tree regression fixture rather than a documented reproduction, say so and I'll add it.

@techomancer
techomancer merged commit d90fa43 into techomancer:main Oct 25, 2026
7 checks passed
belikh added a commit to irix7/iris that referenced this pull request Oct 25, 2026
techomancer#319, techomancer#320 and techomancer#321 are merged upstream and merged back; the send queue is renumbered around them.
@techomancer

Copy link
Copy Markdown
Owner

ps after reconsideration this is probably a no-op nowadays. 500 or so rex3 shaders that are most commonly used are already monomorphised draw functions and are not using the compile queue. there are probably very little compile requests at all. we may want to revisit it and clean it up.

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