Repository navigation
APU Lazy GP EP Execution
Lifecycle: Performance - Unproven · Type: Deliberately destructive observation experiment
Reviewed source:322986f4c5502b3fa887a9605ac8cd88e9b2c579
Warning: This is not a normal performance toggle. It intentionally tests whether guest-visible DSP work can be deferred when host audio is sourced before GP/EP.
APU/DSP investigation directory · DSP JIT qualification · MCPX APU & Audio
When full DSP audio is disabled, the monitor point moves to VP output and GP/EP are marked non-realtime. The frame path still transfers the VP mix into GP X memory. If GP is enabled, the loop still invokes dsp_run(..., 1000) at least once before the non-realtime condition ends the loop. EP can also run on its periodic cadence.
This creates a valid destructive question:
When host audio monitors VP directly, how often do GP/EP side effects become observable to the guest before a later synchronization boundary?
The possible saving is unusually large because a successful route can remove execution of an entire emulated processor for some frames. The risk is equally large: GP/EP are guest-visible processors, not optional host audio effects.
-
hw/xbox/mcpx/apu/dsp/gp_ep.cmcpx_apu_update_dsp_preference()- VP mix write into GP X memory
- GP/EP enable, realtime, cycle and monitor paths
- guest reads/writes of DSP memory and registers
-
hw/xbox/mcpx/apu/dsp/dsp.c- DSP run/memory/peripheral interface
-
hw/xbox/mcpx/apu/dsp/dsp_dma.c- DMA control, descriptors, status and EOL behavior
-
hw/xbox/mcpx/apu/apu.c- frame, interrupt, pause/reset and snapshot lifecycle
flowchart TD
A[APU subframe] --> B[VP produces 32 x 32 mix]
B --> C[Write mix into GP DSP X/mix-buffer alias]
C --> D{GP enabled?}
D -->|Yes| E[Start GP frame and run at least one 1000-cycle chunk]
D -->|No| F[Skip GP]
E --> G{GP realtime and not halted?}
G -->|Yes| E
G -->|No| H[Expose GP memory/status/DMA/interrupt side effects]
F --> I{EP cadence and enabled?}
H --> I
I -->|Yes| J[Run EP cycle chunks]
I -->|No| K[Monitor/output]
J --> K
use_dsp=false changes the host monitor route and realtime policy. It does not prove that guest software stops observing GP/EP.
A safe investigation must treat each of these as a potential demand boundary:
- GP/EP X, Y, P or mix-buffer reads.
- DSP control/status/cycle/halt reads.
- Program or data-memory writes that require ordered execution.
- DMA start, progress, descriptor state, cursor, completion and EOL.
- Interrupt state or notifier publication.
- FIFO reads/writes and scratch-memory side effects.
- Guest logic that polls for DSP completion.
- Snapshot/save-state serialization.
- Reset, pause, engine switch and teardown.
Host audio not listening to GP/EP is only one consumer disappearing. It does not erase these architectural consumers.
Instrument normal execution:
GP/EP cycles executed while use_dsp=false
frames where GP/EP output reaches no host monitor
GP/EP memory reads/writes by source and register range
status/halt/cycle reads
DMA starts, descriptors, status reads and completions
interrupt/notifier changes attributable to GP/EP
snapshot/reset/switch boundaries
first observation after each DSP frame
This phase may close the investigation immediately. If guest observations are frequent, lazy execution is unlikely to be useful.
Continue running the DSP normally, but record whether its work could theoretically have been deferred until the first observation. Maintain a per-frame log:
typedef struct DspObservationWindow {
uint64_t frame_id;
uint64_t gp_cycles;
uint64_t ep_cycles;
uint32_t observation_mask;
uint64_t first_observation_time;
} DspObservationWindow;This estimates removable windows without changing guest behavior.
Only after the census shows large unobserved windows, add a laboratory mode:
if (!g_config.audio.use_dsp &&
!dsp_observation_due_this_frame(d)) {
mark_gp_ep_deferred(d, frame_id);
skip_gp_ep_execution();
} else {
run_reference_gp_ep();
}Every subsequent GP/EP observation must detect deferred state and record why the assumption failed.
void observe_gp_memory(...)
{
if (d->gp_deferred) {
record_deferred_observation(OBS_GP_MEMORY_READ, address);
fail_or_enter_reference_recovery();
}
return reference_read(...);
}The first version should fail closed or mark the run invalid rather than pretending it can reconstruct skipped execution.
flowchart TD
A[APU frame with host monitor at VP] --> B{Observation census predicts GP/EP demand?}
B -->|Yes or unknown| C[Run reference GP/EP]
B -->|No, destructive mode| D[Record deferred frame and skip execution]
D --> E{Later guest observation?}
E -->|No before reset/boundary| F[Count potentially removable work]
E -->|Yes| G[Record first violated assumption]
G --> H[Invalidate performance result / enter explicit recovery experiment]
C --> I[Normal guest-visible state]
F --> I
A later observation may require replaying all skipped inputs in original order:
- VP mix blocks written each frame;
- DSP program/data writes;
- DMA and FIFO events;
- interrupts and peripheral callbacks;
- cycle budgets and halt transitions.
A deferred engine would need a complete input/event log and deterministic replay. That can consume memory and delay the eventual observation more than normal execution.
Therefore, “run when first read” is not a small optimization. It is an alternative timing/execution model and should not be assumed feasible.
Separate modes can answer different questions:
Skip GP only
Skip EP only
Skip both
Run one cycle chunk only
Run DSP but suppress host monitor conversion
Run DSP every N frames
Only the first-observation log and fixed replay workload make these results interpretable. Incorrect audio or game behavior is expected and must be labeled.
- GP instruction execution for unobserved frames.
- EP instruction execution for unobserved periods.
- DSP peripheral callback traffic.
- DMA work initiated only by skipped programs.
- Some APU lock hold time and frame utilization.
- VP processing and mix state.
- Every guest-visible DSP memory/register/DMA/interrupt/notifier effect before observation.
- Correct snapshot/reset/engine-switch state.
- Reference execution whenever demand is unknown.
- An explicit invalid-result marker on any observation of skipped state.
- Measures the upper bound of eliminating an entire emulated DSP route.
- Observation census is useful even if skipping proves impossible.
- Can identify titles and phases where GP/EP are genuinely unused.
- May motivate narrower exact shortcuts, such as skipping only a halted or proven-idle engine.
- Intentionally incorrect until proven otherwise.
- Can alter game logic, not just audio.
- Missing one observation path produces false confidence.
- Deferred replay may be as expensive or more expensive than normal execution.
- Timing changes can hide races or change interrupts.
- Results are title/configuration specific.
- Not appropriate for a normal Advanced menu without a proven contract.
frames_with_use_dsp_false
GP/EP enabled frames
GP/EP cycles executed while host monitors VP
frames with no GP/EP observation
first observation type and delay
GP/EP memory reads/writes
status/cycle/halt polls
DMA activity and status reads
interrupt/notifier events
skipped frames and cycles
invalidated destructive runs
APU frame time saved locally
whole-emulator progress and divergence
| Scenario | Required result |
|---|---|
use_dsp=false, GP/EP disabled |
No false candidate work |
use_dsp=false, engines enabled but unobserved |
Census records window |
| Guest reads GP memory after one skipped frame | Observation trap fires |
| Status polling | Trap identifies exact register/PC |
| DMA starts/completes | Destructive result invalidated unless modeled |
| Interrupt/notifier dependency | Event sequence difference detected |
| GP/EP program or memory write | Ordered demand recorded |
| Snapshot save/restore | No deferred state silently serialized |
| Reset/pause/engine switch | Deferred state invalidated safely |
| Real title fixed replay | First divergence and maximum local cost reported |
This page can move to Researched when the observation census and destructive experiments establish which frames/titles/configurations leave GP/EP unobserved and quantify the maximum removable work. That does not imply the skip is acceptable for implementation.
An implementation candidate requires a much narrower exact condition—such as a halted engine with no pending DMA/interrupt work—or a complete replay model with independent correctness proof.
Reject lazy execution as a product feature when guest observations are frequent, when replay state is too broad, or when the apparent gain comes from lost DMA/interrupt/game behavior. Preserve the negative result as engineering evidence.
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