Restore PGXP page sizing and attribute source publication spans

This commit is contained in:
Shokunin
2026-10-21 22:24:28 -07:00
parent c30fc917c1
commit dd49ca4dc3
4 changed files with 31 additions and 10 deletions
+8
View File
@@ -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.
+1 -2
View File
@@ -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
+17 -3
View File
@@ -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);
@@ -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);