diff --git a/docs/internal/FAITHFUL_TIMING_PLAN.md b/docs/internal/FAITHFUL_TIMING_PLAN.md index 68e0be81..cd9aed4d 100644 --- a/docs/internal/FAITHFUL_TIMING_PLAN.md +++ b/docs/internal/FAITHFUL_TIMING_PLAN.md @@ -2225,3 +2225,11 @@ active checkpoint. Narrow PGXP publication pages from 256 to 64 words to avoid page-boundary/reuse and O0/O2 upload history tests pass. Correct the shared GPU fixture TLS declaration found by that check. No general hot-path changes. Continue ordered production qualification; no push. + +2026-10-21 BRIEF-5 footprint candidate: original-off identity passes, but quiet +regresses to p99 100% (60.000 Hz, zero >25 ms gaps). Revert the smaller PGXP +page size first; keep derived GPU scratch private. Existing host-span receipts +now tag source publication and its RAM/precision/GPU stages so the high-percentile +window can be attributed directly rather than inferred from a sampled mean. +PGXP boundary/reuse checks pass after restoring 256-word pages. Continue ordered +production gates; no general guest hot-path work, no push. diff --git a/runtime/src/pgxp.cpp b/runtime/src/pgxp.cpp index 9833cf37..2530e044 100644 --- a/runtime/src/pgxp.cpp +++ b/runtime/src/pgxp.cpp @@ -96,8 +96,7 @@ struct PGXPValue { #define PGXP_REG_LO 33 static PSX_THREAD_LOCAL PGXPValue *s_ram = nullptr; /* lazily allocated: RAM + mod regions */ -/* Fine publication pages avoid copying 10 KiB for one changed shadow word. */ -enum { PGXP_EXEC_PAGE_WORDS = 64, +enum { PGXP_EXEC_PAGE_WORDS = 256, PGXP_EXEC_PAGES = (PGXP_SHADOW_WORDS + PGXP_EXEC_PAGE_WORDS - 1) / PGXP_EXEC_PAGE_WORDS }; /* Tracking starts only when a replay consumer requests a snapshot. Ordinary * execution does not allocate version tables. A replay marks its modified diff --git a/runtime/src/render_pass_worker.cpp b/runtime/src/render_pass_worker.cpp index bb9a6785..006e2109 100644 --- a/runtime/src/render_pass_worker.cpp +++ b/runtime/src/render_pass_worker.cpp @@ -2,6 +2,7 @@ * values, the worker owns guest execution, and only the render owner consumes * the sealed GPU list. Neither owner waits for an extra frame. */ #include "render_pass_worker.h" +#include "host_span_ring.h" #include "mod_plugins.h" #include "mod_execution.h" #include "mod_runtime.h" @@ -248,10 +249,23 @@ extern "C" int psx_mod_render_pass_async(CPUState *cpu, const PSXModRenderPass * if (g_overlay_flush_pending_cycles) g_overlay_flush_pending_cycles(); job->cpu = *cpu; job->pass = *pass; job->draw = draw; job->bios = psx_bios_active; if (bytes) std::memcpy(job->payload, payload, bytes); + /* Existing host-span receipts separate publication from guest execution. + * Tags: RRAM, RPRE (precision), RGPU, RPUB (whole publication). */ + struct PublicationSpan { + uint64_t start = host_span_begin(); + ~PublicationSpan() { host_span_end(HSPAN_MOD_WORK, start, 0x52505542u); } + } publication_span; + uint64_t stage = host_span_begin(); memory_backing_capture(job->memory); memory_execution_capture(job->metadata); - if (!pgxp_execution_snapshot_capture(job->pgxp) || !gte_execution_snapshot_capture(job->gte) || - !gpu_execution_snapshot_capture(job->gpu) || !gl_renderer_execution_capture(job->gl) || - !overlay_execution_capture(job->overlays)) { ++W.refused; return 0; } + host_span_end(HSPAN_MOD_WORK, stage, 0x5252414Du); + stage = host_span_begin(); + int precision_ok = pgxp_execution_snapshot_capture(job->pgxp) && gte_execution_snapshot_capture(job->gte); + host_span_end(HSPAN_MOD_WORK, stage, 0x52505245u); + if (!precision_ok) { ++W.refused; return 0; } + stage = host_span_begin(); + int gpu_ok = gpu_execution_snapshot_capture(job->gpu) && gl_renderer_execution_capture(job->gl); + host_span_end(HSPAN_MOD_WORK, stage, 0x52475055u); + if (!gpu_ok || !overlay_execution_capture(job->overlays)) { ++W.refused; return 0; } mod_execution_capture(job->mods); dma_snapshot_write(job->dma.get()); timers_get_snapshot(job->timer_counter, job->timer_mode, job->timer_target, job->timer_irq, job->timer_frac); diff --git a/runtime/tests/test_pgxp_execution_snapshot.cpp b/runtime/tests/test_pgxp_execution_snapshot.cpp index 53465f1a..31353dfd 100644 --- a/runtime/tests/test_pgxp_execution_snapshot.cpp +++ b/runtime/tests/test_pgxp_execution_snapshot.cpp @@ -88,19 +88,19 @@ int main() { invalidated.join(); /* Adjacent words across a publication-page boundary remain independent, * including worker writes to a page the source has not changed. */ - seed(8 << 16, address + 252); seed(9 << 16, address + 256); + seed(8 << 16, address + 1020); seed(9 << 16, address + 1024); CHECK(pgxp_execution_snapshot_capture(snapshot)); std::thread boundary([&] { CHECK(pgxp_execution_snapshot_bind(snapshot)); - check(8 << 16, address + 252); check(9 << 16, address + 256); - seed(10 << 16, address + 252); seed(11 << 16, address + 256); + check(8 << 16, address + 1020); check(9 << 16, address + 1024); + seed(10 << 16, address + 1020); seed(11 << 16, address + 1024); pgxp_execution_snapshot_unbind(); }); boundary.join(); - seed(12 << 16, address + 256); + seed(12 << 16, address + 1024); CHECK(pgxp_execution_snapshot_capture(snapshot)); std::thread recapture([&] { CHECK(pgxp_execution_snapshot_bind(snapshot)); - check(8 << 16, address + 252); check(12 << 16, address + 256); + check(8 << 16, address + 1020); check(12 << 16, address + 1024); pgxp_execution_snapshot_unbind(); }); recapture.join(); pgxp_execution_snapshot_destroy(other);