GV7-1d: lockstep drain spins before sleeping

Live MQ65 lockstep run measured 30->6 fps (GS frame 32ms->111ms): the
per-record WaitForEmpty futex round-trip at thousands of records per
frame is almost all of it. Records usually execute in microseconds, so
WaitForEmptyWithSpin catches nearly every drain on the spin path.
Lockstep remains per-record synchronization — the bisect rung, not a
shipping mode; the throughput answer is pipelined mode.

Gates: gs_vertex_tests 21/21; mode-2 gsrunner hashes bit-identical to
GV-0 baselines, all 10 dumps, vk + sw.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Brian Degenhardt
2026-07-19 13:28:29 -07:00
co-authored by Claude
parent 1b5ea8f159
commit 6d998af9ff
+6 -1
View File
@@ -618,8 +618,13 @@ public:
std::this_thread::yield(); // ring full — backpressure
}
// Spin-then-sleep: records usually execute in microseconds, so the spin
// catches nearly every drain without the futex round-trip. Lockstep is
// still per-record synchronization and inherently slow (measured 30->6
// fps on MQ65 with plain WaitForEmpty) — it's the bisect rung, not a
// shipping mode.
if (m_back_lockstep)
m_back_sema.WaitForEmpty();
m_back_sema.WaitForEmptyWithSpin();
}
GSVector4i GetTEX0Rect(GSDrawingContext prev_ctx);