Repository navigation
Peripheral Opportunity Counters
Lifecycle: Performance - Unproven · Type: Instrumentation gate
Reviewed source:322986f4c5502b3fa887a9605ac8cd88e9b2c579
Purpose: Determine whether secondary peripheral paths deserve dedicated optimization investigations before implementation work begins.
APU/DSP investigation directory · Platform & I/O · Timing
Static source review found plausible repeated work in APU idle wakeups, OHCI scheduling, PTIMER conversion, NVNet descriptor handling, and IDE/ATAPI transfer paths. It did not establish that any of those paths materially affect representative gameplay.
Creating five implementation projects now would violate the performance program’s central rule:
frequency × cost × realistically removable fraction × affected workload
This page defines the counters and promotion gates required before any secondary device becomes its own detailed optimization subject.
This shared page spans several subsystems rather than one implementation file. The first instrumentation pass should be attached to the authoritative owner of each event:
- APU idle frame-thread and IRQ activity:
hw/xbox/mcpx/apu/apu.c. - OHCI frame scheduling and ED/TD/ITD DMA: the QEMU OHCI host-controller implementation used by the Xbox board.
- PTIMER MMIO and clock conversion: the NV2A PTIMER implementation and its scheduling helpers.
- NVNet descriptor readiness and accepted-packet routes:
hw/xbox/mcpx/nvnet/. - IDE/ATAPI SG and block transfer paths: the IDE/ATAPI controller and block-layer integration selected by the Xbox board.
Exact file/function names for the non-APU subsystems should be recorded when the counter patch is prepared. The instrumentation page is intentionally not pretending those paths have already been profiled.
flowchart TD
A[Static source observation] --> B[Possible repeated work]
B --> C{Runtime frequency known?}
C -->|No| D[Do not design optimization yet]
D --> E[Add owner-local counters]
C -->|Yes| F{Local cost material?}
F -->|No| G[Keep backlog note]
F -->|Yes| H[Promote to focused investigation]
The current evidence is intentionally incomplete: each device has a plausible pattern, but none has yet crossed the runtime-evidence threshold for its own implementation project.
flowchart TD
A[Source pattern looks repetitive] --> B[Add low-overhead route counters]
B --> C[Release capture in representative workloads]
C --> D{Reached often and costly?}
D -->|No| E[Keep backlog note; no implementation issue]
D -->|Yes| F[Create focused technical investigation]
F --> G[Reference/candidate correctness test]
G --> H[Fixed-work Release A/B]
Counters should identify the owning device, operation, guest PC where useful, and amount of real work—not only call counts.
When the APU is inactive or trapped/halted, the frame thread uses a short timed condition wait. It can also drop the APU lock, acquire the Big QEMU Lock, update interrupts, reacquire the APU lock, and repeat.
This may affect idle CPU use or cross-thread contention. It should not be assumed to explain active gameplay performance.
APU inactive timed wakeups
wakeups caused by condition signal
wakeups caused by timeout
APU lock acquisitions after wake
BQL acquisitions for APU IRQ update
BQL wait and hold time
actual IRQ-level changes
no-change IRQ updates
inactive-thread CPU time
Create a standalone investigation only when inactive wakeups or BQL contention are a measurable contributor to CPU use, battery/thermal load, vCPU ready time, or frame tails.
The board exposes two OHCI controllers. An operational controller can process a 1 ms frame schedule. Ordinary ED/TD descriptors are small guest-memory structures and may be read through several DMA operations, while payload transfers and HCCA handling already use larger operations.
Descriptor batching is plausible but ownership and completion fields are guest-visible in RAM. A bulk snapshot cannot silently delay guest writes or ignore hardware ordering.
configured OHCI controllers
operational controllers
1 ms frame callbacks
empty frame callbacks
ED descriptors visited
TD/ITD descriptors visited
DMA read/write calls by descriptor/payload/HCCA
DMA bytes by category
USB packets submitted/completed
interrupt/status writebacks
callback CPU time and p95/p99
Promote only when representative controller workloads show descriptor DMA dispatch—not host USB latency or payload processing—consuming material CPU time.
A future exact candidate could read one complete descriptor into a local structure, process it, and commit guest-visible fields in the same order. It must handle descriptor mutation, ownership changes, and completion-list updates. This is not yet specified enough for an implementation page.
PTIMER uses general clock conversions and nested integer mul/div behavior. The frequency and register/guest-PC ownership of those calls are unknown. MMIO dispatch may dominate the arithmetic itself.
Any replacement must preserve current truncation. Algebraically combining two ratios can produce a different integer time even when the real-valued formula is equivalent.
PTIMER reads and writes by register
caller/guest PC for hot reads
clock conversion calls
conversion input ranges
muldiv64 host time
alarm scheduling/rescheduling
interrupt transitions
PTIMER total MMIO time
Promote only when PTIMER conversion appears in optimized Release profiles or counters show high-frequency calls with meaningful local cost. Do not create another clock shortcut solely because the expression looks expensive.
Receive readiness may inspect a descriptor even when link, receive-enable, DMA, or ownership state already makes reception impossible. The accepted-packet path may inspect related descriptor state again.
This is a real cleanup opportunity but is network-workload specific.
RX readiness checks
checks rejected before descriptor access
RX descriptor reads during readiness
RX descriptor rereads during accepted packet
TX descriptor reads
packets accepted/dropped
DMA calls and bytes
link-down/disabled checks
NVNet CPU time under traffic and no traffic
Promote when network-heavy traces show descriptor dispatch or repeated guest-memory reads as a meaningful cost. A no-network game is not evidence for or against the route.
The IDE DMA path already constructs scatter/gather lists and transfers sectors in reasonably large chunks. One intermediate copy may remain, but host storage latency, image format, block layer, decompression, and cache misses may dominate.
IDE/ATAPI commands by type
DMA descriptors and SG segments
sector bytes requested
host read/write latency
intermediate copy bytes and CPU time
block-layer wait time
cache hits/misses where available
vCPU wait or guest completion latency
Do not add a direct-transfer implementation page until the intermediate copy is a measured contributor after storage/block latency is separated.
The generic PCI path already avoids rerouting a request when the INTx level does not change. A new generic deduplication project would duplicate existing behavior.
The only remaining opportunities are device-specific: avoid unnecessary work before reaching the already-deduplicated PCI update.
The current board uses normal RAM regions and QEMU PCI/ISA infrastructure. The memory-controller PCI function does not model a rich cycle-level northbridge transaction engine through which all guest memory operations pass.
“Optimize northbridge emulation” is therefore not a useful standalone issue. Investigations should target real code paths such as TCG memory translation, DMA, or device locks.
Counters must be disabled by default and cheap enough to leave compiled into diagnostic Release builds.
typedef struct PeripheralOpportunityCounters {
uint64_t calls;
uint64_t useful_calls;
uint64_t rejected_before_expensive_work;
uint64_t guest_memory_ops;
uint64_t bytes;
uint64_t host_time_ns;
} PeripheralOpportunityCounters;Prefer subsystem/thread-local accumulation and low-frequency snapshot/export. Do not format JSON or take a global contended lock in the hot path.
For operations where guest PC matters, use sampled or bounded heavy-hitter tracking rather than a full unbounded map.
The device-specific sections define their own fields. The shared minimum schema is:
route entries
useful operations
early rejected operations
guest-memory calls and bytes
callback or MMIO CPU time
wait/hold time where synchronization exists
guest PC or workload phase for hot routes
whole-emulator correlation with ready time, frame tails, or I/O completion
flowchart LR
A[Device-owned counters] --> B[Low-frequency snapshot]
B --> C[Join with thread/profile evidence]
C --> D{Frequency and cost material?}
D -->|No| E[Retain backlog note]
D -->|Yes| F[Create standalone subject page]
F --> G[Reference/candidate experiment]
A useful report groups each device by:
| Field | Meaning |
|---|---|
| Calls | How often the route is entered |
| Useful calls | How often real device work occurs |
| Early rejection | How often a cheap bypass could work |
| Guest-memory ops | Dispatch cost around descriptors/state |
| Bytes | Scale of actual transfer |
| CPU time | Inclusive/exclusive local cost |
| Guest PC/title phase | Which workload owns the activity |
| Whole-emulator correlation | Whether the activity aligns with stalls/tails |
Use several workload classes rather than one game:
idle dashboard/menu
controller-heavy title
network traffic test
disc streaming/load transition
PTIMER-heavy title or synthetic timer test
normal gameplay with active APU
Run optimized Release with matching symbols for attribution. Diagnostic counters establish reachability; final acceptance requires an uninstrumented Release candidate.
- Promoting a high call count when each call is negligible.
- Reporting local percentage without the parent thread denominator.
- Batching guest descriptors across ownership/writeback boundaries.
- Changing timer truncation while testing arithmetic cost.
- Treating network or storage-specific wins as universal emulator improvements.
- Leaving high-resolution timers or verbose tracing in the final build.
- Prevents source aesthetics from being mistaken for a real bottleneck.
- Produces reusable evidence even when an optimization is rejected.
- Keeps device-specific counters close to their owning thread and data.
- Allows later subject pages to begin with measured frequency, cost, and workload ownership.
- Avoids large peripheral rewrites whose host I/O or guest ordering dominates.
- Excessive per-call timing can perturb small MMIO and DMA paths.
- Unbounded guest-PC maps or verbose logs can create more overhead than the device.
- Call counts without byte/work denominators can exaggerate importance.
- Counters can become stale when code paths change unless reviewed with the source SHA.
- A shared instrumentation patch can become too broad; each subsystem should be independently switchable.
A secondary device receives its own Performance - Unproven technical page only when counters and profiles establish:
meaningful route frequency
× measurable local cost
× a plausible removable portion
× a representative affected workload
Keep the item in this shared backlog when frequency is low, host I/O latency dominates, the proposed shortcut would weaken guest-visible ordering, or the instrumentation cannot distinguish real device work from framework overhead.
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