zq.py and sylph-run.sh hard-coded '/home/fabi/RE - Project Sylpheed/...'
(the dashed dir was renamed 'RE Project Sylpheed'), so both were broken.
Resolve relative to the script directory now; zq.py honours $SYLPHEED_DB.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
native_active is now folded into parallel_active, so XENIA_NATIVE_THREADS=1
(a) enables kernel.reservations (lwarx/stwcx route through the inter-thread
ReservationTable) and (b) sets kernel.parallel_active for the wall-clock
vsync/coordination paths.
Closes the PPCBUG-108 landmine flagged in the rework pressure-test: native
mode runs guest code on multiple host threads concurrently, so the legacy
per-PpcContext reservation fallback (which cannot observe cross-thread
stores) is incorrect. Previously pure-native (no --parallel) left the table
disabled — silently wrong in release, debug_assert in debug.
Gate GREEN 3/3 (golden byte-identical, native renders, stress no-deadlock).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Scaffolding for the canary-model rework (host-thread-per-guest-thread,
opt-in, non-deterministic). No behavior change with the flag off.
- XENIA_NATIVE_THREADS=1 selects the new executor; folded into the
parallel spawn gate (reuses Arc<Mutex<KernelState>> + worker dispatch).
- native_threads_enabled() = single source of truth for guarded branches.
- run_execution_native(): Stage-0 body delegates to the iterate-4D
free-run executor verbatim (native == freerun for now); Stage 1' will
replace the worker set with one host thread per guest thread.
- native-gate.sh: functional oracle replacing byte-goldens for the MT
path — (1) lockstep golden byte-identity (flag-off safety net),
(2) native render milestone (draws>0 && swaps>0), (3) native deadlock
stress. GREEN 3/3 on current code.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Attacks the ACTUAL bottleneck the profile found (the ~40%-of-worker-time quiesce
barrier — NOT lock contention, which was 4.8%). Removes the per-tick phaser
rendezvous entirely: workers free-run continuously; the coordinator just takes
the kernel lock each tick (like a 7th participant), runs the same housekeeping,
releases, and unparks idle workers.
The only reason the barrier existed was `dispatch_graphics_interrupts` borrowing
a guest thread's ctx as the ISR victim — which races with a worker that has that
ctx EXTRACTED for its unlocked region. Fixed with a per-slot in-flight flag: a
worker sets its bit under the kernel lock right after mem::replace-ing its ctx
out, clears it under the lock after writeback; the coordinator reads the flags
(under the lock → stable snapshot) and passes an in_flight_mask to
dispatch_graphics_interrupts, which SKIPS in-flight slots for victim selection.
Lockstep + the barrier executor pass mask 0 (skip nothing → byte-identical).
Measured (n=2B, JIT): typically ~17s = ~1.4× over lockstep-JIT (~24s), plays the
full video (2.0B instrs, 12041 draws / 7440 swaps — the responsive coordinator
delivers vsync faster so the guest advances more per instruction). Remaining
run-to-run variance (occasional ~65s) is EXTERNAL — the box shows loadavg ~3 and
a `powersave` governor with turbo off; it survived every code change (barrier,
mmio, sync, tick, barrier-removal) precisely because it isn't the code.
Validation: parallel_stress_short 20/20 ok under FREERUN=1; lockstep golden
byte-identical (interp + JIT). Opt-in XENIA_PARALLEL_FREERUN=1.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds XENIA_PARALLEL_PROFILE=1 to the free-run executor: reports, summed across
workers, kernel-lock WAIT (contention), HELD, unlocked REGION, and idle-park
counts. This measured the actual bottleneck before committing to fine-grained
locking — and refuted it:
n=2B free-run profile (worker-thread-time basis):
kernel-lock WAIT = 4.8% <- contention is NOT the wall
kernel-lock HELD = 0.5%
unlocked REGION = 27.1% <- productive
idle_parks = 2.45M ; ~40% = workers blocked at the quiesce barrier
So fine-grained kernel locking would NOT help — the wall is COORDINATION
(the per-tick quiesce barrier + idle-park wake latency) and guest spin-waits.
Also raises the coordinator tick default 200µs -> 2000µs: the barrier is on the
critical path, so the small tick was the dominant cost. This roughly halves the
good-case time (n=2B ~17-18s vs lockstep-JIT ~24s = ~1.35×). BUT free-run is
still BIMODAL — a coordination pathology intermittently latches (~60s). (A/B
tests that looked like "XENIA_GPU_THREAD makes it fast" were run-ordering noise:
use_threaded=true either way — the flag is a no-op here; the split was the
pathology.) Next lever = attack the coordination bimodality (precise cross-slot
wake to kill the ≤50µs idle-park latency; or skip in-flight slots in the ISR
housekeeping to drop the barrier), NOT lock-splitting.
Opt-in (XENIA_PARALLEL_FREERUN=1); lockstep golden byte-identical (interp+JIT).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Removes the per-round phaser barrier that capped the coarse parallel path at
~parity. Workers now FREE-RUN their HW slots (pick slot's thread, run a
parallel-safe region on the extracted ctx, writeback+epilogue under the lock,
repeat — no waiting on peers); a coordinator thread runs the same housekeeping
(coord_pre_round tickers/timers, dispatch_graphics_interrupts, inline-GPU drain,
coord_idle_advance) only on a wall-clock cadence, quiescing the workers at a
7-party phaser (via a global `quiesce` AtomicBool, robust vs the earlier
epoch-diff which desynced a late-starting worker) so ctx-borrowing housekeeping
stays race-free.
New: run_execution_parallel_freerun, parallel_region_budget() (default 2048,
XENIA_PARALLEL_BUDGET; decoupled from lockstep's 128 so the golden is
untouched), scheduler slot_runnable()/any_runnable(), a per-thread `retired=`
field in the XENIA_DUMP_SLOTS diagnostic, and dropping the global
mmio_access_count region break in the parallel driver (that shared counter,
bumped by ANY worker, collapsed every region to one block).
STATUS — correct but NOT yet a win. Measured (n=2B, --gpu-inline, JIT):
- runs the full 2B and plays the video (4939 draws / 1361 swaps).
- BIMODAL: good runs ~21s (edges out lockstep-JIT's ~24s) but a
kernel-mutex-contention / guest-spin-wait pathology intermittently latches
and makes a run 2-3x slower (~57-87s).
Root cause: the single Arc<Mutex<KernelState>> serializes the 6 workers, so the
~4.3x thread-parallelism the workload exposes (measured: work spread across
~5-8 balanced guest threads, top only ~7%) collapses to ~parity. Region-tuning
levers (barrier granularity, MMIO break, GPU cadence, sync break) were each
measured and none crack it — the real win requires FINE-GRAINED kernel locking.
Gated OPT-IN behind XENIA_PARALLEL_FREERUN=1; default --parallel stays the
per-round barrier executor. Lockstep untouched (6-config golden byte-identical);
parallel_stress_short 20/20 ok under FREERUN=1.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The --parallel worker did a full 7-party phaser barrier + kernel-lock dance
around every single ~13-instruction interpreter block, making it 20x SLOWER
than lockstep (2.7 vs 55 MIPS at n=400M) and JIT-less. Replace the single-block
unlocked window with run_superblock_parallel_unlocked: a whole straight-line
region on the extracted ctx + per-worker caches (block + JIT), stopping at the
first import/halt/mmio/sync/budget boundary for the locked epilogue to handle.
Touches zero KernelState in the lock-free window (thunk band cached once under
the lock via new KernelState::thunk_addr_band). Same JIT seam as run_superblock,
so XENIA_JIT unset = interp, set = JIT — one driver covers Phase A and B.
Measured (--gpu-inline):
- recovered the parallel path 16-30x (2.7 -> 43-95 MIPS)
- video-phase n=2B parallel-JIT budget=8192: 21.0s vs lockstep-JIT 23.8s (+13%),
but violently budget-fragile (4096 = 79.9s) -> the hard per-round barrier +
load imbalance caps it well below the 4.3x runnable-width ceiling. Phase C
(free-running workers) needed for the real multiplier.
Determinism: lockstep path untouched; 6-config n=200M golden byte-identical
(incl. config6 JIT+chain+budget=1 == interp+budget=1). xenia-jit 24 tests green;
parallel_stress_short 20/20 ok.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 16:50:42 +02:00
6 changed files with 856 additions and 23 deletions
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.