Repository navigation
x4prosim: X3 CPU instruction costs calibrated to the ESP32-C3 - #6
Merged
Merged
Conversation
Keep translation block instruction counts separate from virtual-time costs, including timer budget conversion and exception refunds. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T57W7AZf7tgmkuDMMSaWwz
Retain clock-register writes, derive the CPU cost multiplier, and flush translations when it changes; preserve the existing 80 MHz reset state and record boot timing and register evidence. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T57W7AZf7tgmkuDMMSaWwz
Use nanosecond region costs for X3 and fit instruction surcharges against the CPU probe and page-rendering measurements. Reduce SPI setup charges and refit SD stop busy time after accounting for the slower guest driver. Record CPU, SD, reading, panel, and clock validation with the remaining residuals. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T57W7AZf7tgmkuDMMSaWwz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on the panel timing branch; the three new commits are the CPU ones.
Under
-icount shift=2every guest instruction cost 4 ns, a 250 MIPS CPU with free memory. A probe firmware (tight SRAM loop, cached and cache-thrashing flash code, loads/stores, memcpy, mul/div, soft-float, calls, and the firmware's own text layout and glyph rendering) measured the real ESP32-C3 at 160 MHz against that: SRAM code runs 2.0x slower than the emulator, ROM library code 1.7x, cached flash code 2.2x, multiply 2.6x, divide 10x, and code that misses the 16 KB instruction cache 41x. Page rendering in CrossPoint sat at 2.7x.Model
accel/tcg/translator.c,include/exec/translator.h: an optional per-targetinsn_costhook.tb->icountand theCF_COUNT_MASKbudget still count instructions; a separateicount_costis what the icount decrementer charges, with per-instruction costs in the unwind table so exceptions and MMIO re-translation refund unexecuted ticks. Targets bound the TB length so a block's cost fits the 16-bit counter.target/riscv/translate.c,cpu.c: costs as CPU properties, in nanoseconds, by the instruction's region (ROM 0x40000000, SRAM, the flash cache window 0x42000000) plus surcharges for loads, stores, mul, div and branches, times a clock factor.hw/riscv/esp32c3_clk.c: the SYSTEM clock registers now drive that factor (160 MHz = 1x, 80 MHz = 2x, 10 MHz = 16x) and flush translations on a change, so the firmware's low-power mode after 3 s idle really slows it 16x, andgetCpuFrequencyMhz()reads 160 instead of 80. The pre-app boot phase at 80 MHz is kept faithful (about 130 ms longer than before).-icount shift=0(1 ns ticks) inrun.sh/drive.py; defaults ROM/SRAM/flash 6/8/10 ns, store +3, div +160, branch +2. The SD bus setup terms were re-fitted on top (GPSPI 700 + 300 ns), all 30 SD probe rows still within 5 % / 15 %.Calibration
Probe rows device vs emulator after calibration: sram_loop +3 %, memcpy +6 %, memset 0 %, mul +2 %, div -8 %, fmul -6 %, fdiv +9 %, dmul -6 %, call_ret +10 %. The flash base is set for page rendering rather than tiny cached loops, so the small cached loop, the load/store loops and the probe's layout/glyph paths read 15 to 33 % slow. Code that thrashes the cache is still 16x too fast: a static penalty cannot model that; an instruction-cache model is the next step if it ever matters. Full tables:
x4prosim/sdcal/cpu.md.Reading workload, device vs emulator (ms, median of 6 page turns)
Cold-open first render: Aesop 3495 vs 3575 ms, Demian 3437 vs 3486 ms. Before any of the three timing branches the emulator reported 683 and 704 ms per turn.
Error of the emulator against the device, same runs (negative = emulator faster; medians of 6 turns on one boot per side, and the device's own turn-to-turn spread is about 5 %, so differences under about 3 % are noise):
The residual is systematic: the emulator is a few percent fast everywhere except the panel refresh, which is exact. The grayscale passes read SD-font glyphs with a tail-heavy latency the card model represents by its median, and
cleanupis a 52 KB plane write whose driver cost is still about 6 % under the device; both are property changes if they ever need closing. Aesop's cold-open prewarm is a 21 ms stage, so its -14 % is 3 ms.Limits
🤖 Generated with Claude Code
https://claude.ai/code/session_01T57W7AZf7tgmkuDMMSaWwz