Repository navigation
Hot Path vCPU REP MOVS RAM Chunks
Lifecycle: Performance - Unproven · Type: Memory shortcut
State: Source-backed; runtime value is not established.
Status: Source-validated shortcut candidate; not implemented or benchmarked.
Mechanism class: Runtime-admitted bulk-memory bypass of repeated guest load/store iterations.
Reviewed source:
322986f4c5502b3fa887a9605ac8cd88e9b2c579Primary files:
target/i386/tcg/emit.c.inc,target/i386/tcg/translate.c, TCG SoftMMU/TLB and dirty/invalidation code.
Current xemu already keeps REP MOVS inside translated execution; it does not necessarily return to the main dispatcher for every copied element. The emitter routes MOVS through:
gen_repz(s, ot, gen_movs);The remaining expansion is inside the loop: each element still requires guest source/destination address work, a generic guest load and store, index updates, and count/loop handling.
The proposed shortcut admits a bounded ordinary-RAM span once and replaces many per-element operations with one native bulk copy, followed by an exact guest-progress commit.
This is a genuine shortcut because the general SoftMMU iteration remains available for MMIO, faults, overlaps, code pages, watchpoints, reverse direction, short counts, and every unproven case.
flowchart TD
A[Guest REP MOVS] --> B[Translated repeat loop]
B --> C[Calculate guest source and destination]
C --> D[Guest load through normal memory path]
D --> E[Guest store through normal memory path]
E --> F[Update ESI/EDI and ECX]
F --> G{Count remains and no required exit?}
G -->|Yes| B
G -->|No| H[Continue/exit guest execution]
This route is general and preserves per-element faults, side effects, memory-type routing, dirty tracking, code invalidation, watchpoints, direction, and interruption points.
The first experiment should admit only:
instruction: REP MOVSB
address size: one explicitly tested mode
DF: clear / forward
count: above a minimum threshold
source and destination: ordinary RAM
source and destination spans: within currently admitted page/window
overlap: rejected
watchpoints/breakpoints: absent
MMIO/ROM/aliases: rejected
write permission: proven
code-page/self-modifying-code responsibility: understood or rejected
chunk length: bounded for interrupts and device progress
Do not begin with reverse direction, element widths above one byte, overlap, cross-page spans, or raw writes to translated code pages.
flowchart TD
A[Guest REP MOVSB] --> B{Candidate mode and count threshold?}
B -->|No| R[Reference translated iteration]
B -->|Yes| C[Resolve source and destination access]
C --> D{Both ordinary RAM and safe bounded spans?}
D -->|No| R
D -->|Yes| E{Forward and non-overlapping?}
E -->|No| R
E -->|Yes| F[Choose min of count, source span, destination span and chunk cap]
F --> G[Execute native bounded copy]
G --> H[Perform required dirty/code-invalidation publication]
H --> I[Commit exactly completed ESI, EDI and ECX progress]
I --> J{Count remains and no exit/interrupt pending?}
J -->|Yes| C
J -->|No| K[Retry/continue architectural guest path]
Illustrative helper shape:
/* Interfaces are illustrative, not current xemu APIs. */
size_t chunk = admit_rep_movsb_ram_chunk(env, src, dst, count);
if (chunk != 0) {
execute_native_copy(src_host, dst_host, chunk);
publish_guest_write_effects(dst, chunk);
commit_rep_movs_progress(env, chunk);
return;
}
execute_reference_iteration(env);The candidate should retry the architectural loop after every bounded chunk. This preserves a clear place to observe exit requests, interrupts, changed mappings, and remaining count.
The possible avoided work is:
- repeated software-TLB probes for source and destination;
- repeated slow-path labels/branches;
- per-element guest address calculation;
- per-element ESI/EDI/ECX updates;
- per-element loop branches;
- repeated load/store helper transitions when an access misses the fast path.
A rough opportunity model is:
eligible bytes copied
× current memory-access/check cost per byte
- admission and chunk-publication cost
Small copies may lose. Measure count distributions and admitted bytes before selecting a threshold.
Guest MOVS is architectural execution, not a generic library copy.
Sequential MOVS behavior can differ from memcpy() and memmove() when ranges overlap. The first shortcut rejects overlap rather than selecting a library function by intuition.
A fault can occur after some elements have completed. Guest indices/count must represent exactly completed work. Restricting a chunk to already admitted page/window spans avoids claiming progress across an unvalidated second page.
Raw host writes may need to publish:
- dirty-memory state;
- translated-code invalidation for self-modifying guest code;
- display/device client dirtiness;
- watchpoint/debug events;
- snapshot/migration dirtiness;
- write-protection/fault behavior.
If those responsibilities cannot be satisfied cheaply and exactly, the candidate must reject the range.
Large guest REP operations can be interruptible between iterations. A single unbounded host copy can delay interrupts or device progress. Use a conservative chunk cap and recheck exit/interrupt state between chunks.
A valid source plan must prove:
- current guest virtual-to-physical translation;
- readable permission;
- ordinary RAM backing;
- contiguous host bytes for the admitted length;
- no watchpoint or side-effecting memory region;
- mapping/TLB epoch remains valid for the operation.
A valid destination plan must additionally prove:
- writable permission;
- complete dirty/code invalidation handling;
- no ROM/MMIO/alias behavior requiring callbacks;
- no unsupported overlap with the source.
Do not reuse an admitted host pointer across unrelated guest instructions without a mapping-generation design. The first experiment resolves each chunk at runtime.
| Area | Role |
|---|---|
target/i386/tcg/emit.c.inc::gen_MOVS() |
Instruction translation entry |
gen_repz / gen_movs path |
Current translated per-element loop |
| TCG SoftMMU/TLB access generation | Current source/destination memory checks |
RAM MemoryRegion/address-space mapping |
Host pointer and span admission |
| dirty-memory and TB invalidation | Required destination publication |
| CPU exit/interrupt state | Chunk interruption/fairness |
| ESI/EDI/ECX architectural state | Exact progress commit |
| Counter | Unit | Meaning |
|---|---|---|
rep_movs_exec |
instructions | Dynamic use |
rep_movs_requested_bytes |
bytes | Total guest request size |
rep_movs_candidate_attempts |
chunks | Admission tried |
rep_movs_admitted_chunks |
chunks | Native route entered |
rep_movs_admitted_bytes |
bytes | Useful work bypassed |
rep_movs_reference_bytes |
bytes | General route retained |
rep_movs_reject_* |
chunks | Count, direction, overlap, page, MMIO, watchpoint, code, permission, mapping |
tlb_checks_avoided |
estimated/actual operations | Local work removal |
chunk_exit_checks |
checks | Interruptibility overhead |
fault_progress_mismatches |
cases | Correctness failure |
Report the distribution of chunk sizes. A high hit count consisting only of 4-byte chunks can be slower than the reference.
- zero count;
- one byte;
- below/at/above admission threshold;
- source ending at page boundary;
- destination ending at page boundary;
- unmapped or protected second page;
- maximum bounded chunk and multi-chunk completion.
- ordinary RAM;
- ROM/read-only destination;
- MMIO source or destination;
- RAM alias/remap;
- watchpoint;
- translated code page/self-modifying destination;
- snapshot/dirty tracking active.
- forward non-overlap positive case;
- forward overlap in both relative directions — must reject initially;
- DF set — must reject initially;
- different address-size/count register modes;
- source/destination wraparound;
- interrupt/exit request between chunks;
- mapping invalidation between chunks;
- fault after partial reference progress.
Deliberately allow one unsafe cross-page or overlap case in a test build. The oracle must detect wrong data, wrong fault point, or wrong architectural progress.
large REP MOVSB operations are dynamically common
admitted bytes are substantial
per-byte TLB/address/bookkeeping operations fall
host copy execution becomes visible
vCPU time per fixed copy workload improves
retail guest progress improves or CPU falls
fault, dirty and architectural progress remain exact
A synthetic memory test alone is insufficient. Identify titles or boot/runtime operations that actually execute eligible copies.
- Claiming the current implementation dispatches once per byte when it already loops in translated code.
- Replacing overlapping MOVS with
memcpy(). - Crossing a possible fault boundary and over-advancing guest state.
- Bypassing write dirtying or self-modifying-code invalidation.
- Treating MMIO/ROM/aliases as RAM.
- Holding stale host pointers across mapping changes.
- Copying so much at once that interrupts/device progress are delayed.
- Setting a threshold without measuring copy-size distribution.
- Using total copied bytes without proving shortcut admission.
- Count REP forms, direction, count distribution, memory class, and hot guest PCs.
- Build a source/destination span-admission diagnostic without changing execution.
- Implement only forward non-overlapping
REP MOVSBwithin admitted RAM spans. - Bound chunks to one proven window and a conservative interrupt cap.
- Preserve the reference loop for every rejection.
- Build exact data, register/count, fault-point, dirty-state, and invalidation tests.
- Inspect optimized generated code and memory slow-path counts.
- Measure synthetic fixed-byte work and representative titles separately.
- Expand widths/directions/pages only as independent follow-up experiments.
- vCPU Shortcut Candidates
- TCG Direct-RAM Read Windows
- CPU & vCPU Execution
- Memory & DMA
- Debugging Lag & Hot-Path Analysis
Primary reference: This subject page is the design and research reference for REP MOVS RAM Chunks. Pull requests are implementation/test history only.
Lifecycle: Performance - Unproven · Mechanism: Bounded guest-memory loop shortcut
Reviewed source:322986f4c5502b3fa887a9605ac8cd88e9b2c579· Acceptance class: intended exact or behavior-preserving for its admitted scope
For a narrow admitted forward non-overlapping RAM case, copy a bounded chunk natively instead of executing generic guest address/load/store/bookkeeping for every element.
This entry remains Unproven: the source path and opportunity are concrete, but no accepted xemu runtime result has established that the candidate improves representative workloads. The page defines what must be bypassed, what remains mandatory, and how the hypothesis can be rejected.
| File / function | Role |
|---|---|
target/i386/tcg/translate.c |
REP MOVS translation and in-TB loop |
tcg/* |
guest memory access, dirty tracking and code invalidation |
flowchart TD
N0["Per element: compute source/destination"]
N1["Guest load"]
N0 --> N1
N2["Guest store"]
N1 --> N2
N3["Advance ESI/EDI"]
N2 --> N3
N4["Decrement ECX"]
N3 --> N4
N5["Check loop/exit"]
N4 --> N5
N6["Repeat"]
N5 --> N6
flowchart TD
N0["Admit bounded ordinary-RAM spans"]
N1["Select safe chunk"]
N0 --> N1
N2["Native copy/rep movsb"]
N1 --> N2
N3["Publish dirty/code invalidation"]
N2 --> N3
N4["Commit exact guest progress"]
N3 --> N4
N5["Check interrupt/remaining count"]
N4 --> N5
N6["Fallback otherwise"]
N5 --> N6
Current implementation already loops inside translated code, so the opportunity is not 'avoid dispatcher per byte.' It is remove repeated generic memory preparation and register bookkeeping for a common safe span. Fault and partial-progress semantics make an unrestricted memcpy replacement invalid.
- Repeated software memory-access setup per element
- Repeated index/count bookkeeping
- Some loop branches
- Dirty tracking and translated-code invalidation
- Interruptibility
- Fault/partial progress
- Overlap/direction semantics
- MMIO/watchpoint fallback
; After narrow admission has produced host pointers and a safe count
mov rsi, host_src
mov rdi, host_dst
mov rcx, admitted_count
rep movsb
; Then commit guest ESI/EDI/ECX for exactly rcx completed bytes.The sketch defines the intended boundary; it is not a complete patch and does not replace source review, ownership design, or focused tests.
- Initial route is REP MOVSB, forward, non-overlapping, ordinary RAM.
- Chunk stays inside validated mappings and a bounded interrupt interval.
- Guest registers reflect exact completed progress on exit/fault.
- Destination dirty/code invalidation is correct before later execution.
Admission is per chunk; host pointers do not survive remap/TLB changes. Chunk size bounds interrupt latency. Writes to code pages trigger required invalidation. Any overlap, backward direction, watchpoint, MMIO, permission/fault ambiguity uses reference iteration.
The maintained reference path remains the fallback whenever admission, capability, lifetime, or validation is uncertain. A fast result with an unproven dependency is not acceptable as an exact optimization.
- Can remove large amounts of generated memory-loop overhead
- Native string engines are highly optimized
- Clear size/eligibility counters
- Narrow exact subset possible
- Fault/partial progress complexity
- Overlap semantics
- Dirty/code invalidation
- Interrupt latency
- Small copies may lose to setup
- Backend/host variation
Counters must be cheap, subsystem-owned, and snapshotted outside the hot loop. Record at least:
- REP_MOVS_invocations
- requested_bytes
- admitted_bytes
- chunk_size_distribution
- reference_rejections_by_reason
- memory_checks_avoided
- faults/interrupts
- CPU time per fixed copy
A local reduction is not enough. Evidence must connect route reachability and removed work to fixed guest progress, CPU/GPU time where applicable, and p95/p99 behavior.
- Zero/tiny/large counts
- Page boundary and unmapped second page
- Forward/backward
- Overlap patterns
- Code-page destination
- MMIO/watchpoint rejection
- Interrupt during long copy
- Partial progress/fault
- Random differential memory/register state
Correctness runs may use validation layers, detailed comparisons, and fault injection. Performance acceptance must use optimized Release builds with matching symbols and minimal instrumentation.
Promote only a narrow subset after exact progress/fault/invalidation tests and representative workloads show common large admitted chunks.
Reject broad memcpy/memmove substitution, unbounded chunks, or any path that cannot reproduce guest progress and memory side effects.
CPU-and-vCPU-Execution · Performance-Unproven · Hot-Path-TCG-Direct-RAM-Read-Windows · Memory-and-DMA
PR pages may be linked as supporting evidence, but they are not substitutes for this reference.
DSP tooling guide and navigation updated November 2, 2026 for experimental PR #384, source 8f51d237. Capture/replay usage and limits.
The earlier wiki-wide review was published November 1, 2026. Emulator source: b7140848. Reviewed wiki content: 1d2b671. Current status · Release availability · Publication process.
- Home
- Current status
- Stable versus main
- Implemented mechanisms
- Controls and defaults
- Measured results and limits
- Complete change register
- System
- CPU and vCPU
- Memory and DMA
- Graphics / NV2A
- APU and audio
- Timing and timers
- Platform and I/O
- Hardware observations
- Fidelity boundaries
- Methodology
- PGR2 routes
- Debugging lag / hot paths
- Tools and commands
- DSP capture, replay and fuzzing
- HLE readiness and public XISO proof
- Concurrent DSP shadow and OpenAL proof
- DSP HLE operation inventory
- DSP HLE fix examples and testing
- Development
- Upstream shortlist
- Wiki maintenance
- Research / retired work
- Optimization catalog
- Hot-path shortcuts
- Researched experiments
- Unproven proposal directory
- PR lessons
- September26 snapshot
Repository · PRs · Issues