Skip to content

APU Lazy GP EP Execution

github-actions[bot] edited this page Sep 15, 2026 · 1 revision

Experimental Lazy GP / EP DSP 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

Purpose

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.

Source seams

Current execution flow

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
Loading

use_dsp=false changes the host monitor route and realtime policy. It does not prove that guest software stops observing GP/EP.

Guest observations that make execution mandatory

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.

Investigation phases

Phase 1: observation census without changing behavior

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.

Phase 2: shadow deferral model

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.

Phase 3: destructive skip-and-trap experiment

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.

Candidate execution flow

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
Loading

Why catch-up is difficult

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.

Destructive upper-bound modes

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.

What may disappear

  • 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.

What remains mandatory

  • 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.

Advantages

  • 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.

Costs and risks

  • 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.

Required counters

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

Qualification matrix

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

Acceptance rule

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.

Rejection rule

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.

Related

Clone this wiki locally