Expand description
Where a run’s time and work actually go.
A machine like this has three phases, and they have wildly different costs per occurrence and wildly different frequencies:
- Fetch — reading instruction bytes out of guest memory, through the MMU’s execute permission.
- Decode and lift — turning those bytes into QCode, plus the cleanup round over the result.
- Execute — interpreting the QCode.
Fetch and lift happen once per distinct instruction; execute happens once per instruction executed. So the split depends entirely on the workload: a tight loop is almost all execute, while a long straight-line run is dominated by lifting. Reporting one number for “throughput” without saying which workload produced it is how a benchmark misleads.
Counting is always on and costs a few increments. Timing is only taken around lifting, which is rare; putting a clock read around each interpreter step would cost more than the step. Execute time is therefore derived — wall clock minus the measured phases — rather than measured directly.
Structs§
- Stats
- Counters and timings for one machine’s run.