Repository navigation
Shadowcache - #216
Merged
Merged
Shadowcache#216
Conversation
…PACT JIT The GUI, the release binaries and profile.sh now build with gpujit (rex-jit + gr4-jit) instead of rex-jit alone, so IMPACT gets its raster JIT out of the box; the docs recommend `--features lightning,gpujit`. IRIS_NO_JIT, which the Mac App Store build sets because its sandbox kills Cranelift's executable pages, now turns the IMPACT raster JIT off as it already did the REX3 one: rss_jit::forbidden() makes the default mode off, and `mgras jit on|sync` refuses. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Fixes found running SGI's own IP22 IDE against the full cache model. On R4400, IDE icache2 now passes. - Index_Store_Tag(SD) indexed the secondary by the TagLo value instead of the CACHE address (R4000 UM A-42, VR5000 UM 3.4). Init stores TagLo = 0, so it only ever hit set 0, and a round-trip test masked it. - Index_Load_Tag returns generated check bits: primary P (even parity) and the R4400 secondary tag ECC (UM Figure 16-4). Computed on read, nothing stored; the hardware ignores them on Index_Store_Tag. - R5000 primary TagLo uses the R4400 PState encoding (I valid = 2, D clean = 2, dirty = 3), as IDE icachetag/set_tag and IRIX mcparity.c expect on every IP22 CPU. The D(7)/V(6) layout came from a critique and failed icachetag. - Hit_Writeback(I) wrote nothing. It now writes the words the line was filled with back to L2 or memory. R4400 keeps a fill-time snapshot (ic_raw), since its fetch path serves the L2 decode slots; R5000's ic_instrs already is the copy. Only the I-cache miss path gains work. - Snapshot restore rebuilds I-cache words. A restored valid R5000 line was served from empty slots (NOPs) until evicted. Parity/ECC injection (IDE dcache1, icache1, scache1) is still missing. Co-Authored-By: Claude Opus 5.5 <[email protected]>
With --features cache-ecc, every IP22 IDE cache test (icache1, icache2, dcache1, scache1) passes on R4400 and R5000. Off by default: nothing but a diagnostic ever observes check bits, and gated off the hooks compile away. - Cache Error: EXEC_CACHE_ERR sets ErrorEPC and ERL, jumps to 0xA0000100 or 0xBFC00300 (BEV), and leaves Cause/EPC/EXL/BadVAddr alone. CacheErr comes from the cache. - Status.CE: a store takes the ECC register as the check bits of the bytes it writes, Fill(I) as the line's parity, and a D-cache write-back by a CACHE op XORs it into the L2 ECC of the addressed doubleword. - Detection with DE and ERL clear: D-cache loads, primary refills from L2 (EC), and Hit_Writeback(I), which faults from the CACHE instruction. - Index_Load_Tag loads CP0 ECC with the selected doubleword's check bits; the L2 data matrix is R4000 UM Figure 16-1. - Check bits are only stored when forced. A line that needs checking carries L1DTag::SLOW, so it fails the exact tag compare (interpreter and jitv2 inline guard) and is resolved on the miss path: no hit-path cost. Always on, not gated: Fill(I) on the 2-way R5000 refills the way already holding the line (IDE pins lines with Index_Store_Tag first), which fixes icache2 there. Co-Authored-By: Claude Opus 5.5 <[email protected]>
ShadowCache (memory is the only store, tags answer CACHE ops) now covers the R4400 and R5000 as well as the R10000, chosen by MODEL as CpuCache is: CACHE index ops pick lines as the full model does (R4400 direct-mapped, R5000 way = VA[14], R10000 way = VA[0]), and R4400/R5000 tags read back exactly as the full model's, through shared r4k_store_taglo/r4k_load_taglo. `[machine] cache = auto|full|shadow` and `--cache` (also `iris-bench run --cache`) pick it at machine build. auto is shadow in a jitv2 build, full otherwise: jitv2 full-length iris-bench, shadow vs full, R4400 x1.33, R5000 x1.50 geomean, while the interpreter re-decodes every instruction against the shadow and is about x0.55-0.6. The R10000 only has the shadow. Snapshots record cpu_cache; restoring into the other model is refused. Legacy manifests mean the old default. cpu-tests: the shadow loses only cache/hit_inv_discards, as jitv2's tcache already did. Two more monomorphised CPUs: +4.3% .text. Co-Authored-By: Claude Opus 5.5 <[email protected]>
The shadow cache keeps no lines, so the interpreter re-decoded every instruction and reached RAM through a BusDevice call for every fetch and data access. - decode-cache (src/cpu/decode_cache.rs): decoded instructions by physical page, used by ShadowCache::fetch only, never touching its tag arrays. Each fetch re-reads the word (and a fused pair's next word) and reuses the decode only if unchanged, so it is exactly coherent with memory. jitv2's page write generations were tried as the validator and measured no faster. - The shadow reads and writes RAM through ppmem's window in every build: the window hand-over is no longer gated on tcache. Decoded pages keep a pointer to their window page; PROM, MMIO and the low alias have none and use the bus. A region-bitmap change (remap), power-on or restore starts the cache over. - The fetch hit path is inlined, the fill and bus paths cold. - The shadow now clears its tags on power-on. Shadow vs full: interpreter x1.36 (R4400), x1.03 (R5000); jitv2 x1.52 on both; accuracy identical. jitv2 implies decode-cache. auto stays: full cache for the interpreter, shadow under jitv2. Co-Authored-By: Claude Opus 5.5 <[email protected]>
1431f56 grew fill_l1i_line (the ic_raw snapshot), which was inlined into fetch, and fetch stopped inlining into step_int: every interpreted instruction paid a call. Bare-metal iris-bench (lightning, R4400, full cache) dropped to x0.84 of main, sys/uncached to x0.51. fetch is the per-instruction hit path, so it is #[inline(always)]; fill_l1i_line is the miss path, so #[inline(never)] #[cold], and its size can no longer decide the hot path. Back to x1.02 of main. Co-Authored-By: Claude Opus 5.5 <[email protected]>
It is a win wherever the shadow runs, interpreter and jitv2 alike, and costs nothing elsewhere: it is only reached from ShadowCache::fetch. The decode-cache feature is now a no-op kept for existing command lines, as tlbvmap is, and jitv2 no longer lists it. ShadowCache's old per-fetch bus read into a scratch slot is gone with the gate. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
shadow cache and decode cache based on physical memory.
should boost jit on r4k and r5k and help jit -> int fallback performance.