From daa537bfe8ac67d315cbdeff34b9e3090b171923 Mon Sep 17 00:00:00 2001 From: megboyzz Date: Sun, 20 Sep 2026 03:59:47 +0300 Subject: [PATCH] Verify the exit-check removal at 6.3%; record the TLB experiment as refuted Two results, one positive and one negative. CONFIRMED - removing the exit-request check from the guest load/store path (ea079b8) is worth 6.3%. That commit went in on a single A/B pair because the device wedged mid-measurement; re-run on a freshly rebooted Pixel 6a, three interleaved pairs, load to first OnCarLoaded: without the check: 33.42 / 33.10 / 33.32 s mean 33.28 with the check: 35.62 / 35.43 / 35.49 s mean 35.51 Ranges do not overlap and each spread is under a third of a second. REFUTED - raising CPU_TLB_DYN_DEFAULT_BITS from 8 to 12. The premise checked out: a probe in tlb_mmu_resize_locked showed it runs only about twice per second and current_entries stayed at 256 for a whole run, so the adaptive TLB genuinely never grows for this workload and sits at 1 MB of coverage against a working set of hundreds of MB. Raising it took effect (current_entries=4096, verified live) and bought nothing: 12 bits: 32.36 / 32.26 s 8 bits: 32.86 / 32.32 s 0.28s apart, ranges overlap The profile moved the WRONG way - tlb_set_page_with_attrs 0.86% -> 2.92%, since a larger TLB costs more to fill and flush. So the softmmu lookup cost (flatview_translate + find_memory_mapping, ~7.5%) is not driven by TLB capacity. Reverted to the upstream default, with the refutation recorded in place so nobody retries it without a new theory. Also removes the temporary TLB probe. Worth noting for future measurements: after the device was rebooted, the same build measured ~33s where it had measured ~41s before. The earlier drift was device state, not code. Co-Authored-By: Claude --- .../unicorn/qemu/include/exec/cpu-defs.h | 20 +++++++++++++++++++ .../cpp/third_party/unicorn/qemu/tcg/tcg-op.c | 8 ++++++++ 2 files changed, 28 insertions(+) diff --git a/mpcore/src/main/cpp/third_party/unicorn/qemu/include/exec/cpu-defs.h b/mpcore/src/main/cpp/third_party/unicorn/qemu/include/exec/cpu-defs.h index 5c11015..9b14476 100644 --- a/mpcore/src/main/cpp/third_party/unicorn/qemu/include/exec/cpu-defs.h +++ b/mpcore/src/main/cpp/third_party/unicorn/qemu/include/exec/cpu-defs.h @@ -83,6 +83,26 @@ typedef uint64_t target_ulong; #endif #define CPU_TLB_DYN_MIN_BITS 6 +// NFSMW arm64-poc, 2026-09-19: raising this to 12 was TRIED AND REFUTED. +// +// The reasoning looked sound: 8 bits = 256 entries x 4KB = 1 MB of guest +// coverage against a working set of hundreds of MB, and +// tlb_mmu_resize_locked resizes ONLY on a TLB flush. Measured on device, +// that function runs about twice per second and current_entries stayed at +// 256 for a whole run - so adaptive growth genuinely never helps here. +// +// Setting 12 (4096 entries, 16 MB covered) did take effect - verified live, +// current_entries=4096 - and bought nothing: +// +// interleaved A/B, load to first OnCarLoaded +// 12 bits: 32.36 / 32.26 s +// 8 bits: 32.86 / 32.32 s (0.28s apart, ranges overlap) +// +// The profile actually moved the wrong way: tlb_set_page_with_attrs went +// 0.86% -> 2.92%, because a larger TLB costs more to fill and flush. So the +// softmmu lookup cost (flatview_translate + find_memory_mapping, ~7.5%) is +// NOT driven by TLB capacity. Left at the upstream default; do not retry +// without a different theory for where those misses come from. #define CPU_TLB_DYN_DEFAULT_BITS 8 # if HOST_LONG_BITS == 32 diff --git a/mpcore/src/main/cpp/third_party/unicorn/qemu/tcg/tcg-op.c b/mpcore/src/main/cpp/third_party/unicorn/qemu/tcg/tcg-op.c index df33255..6769d11 100644 --- a/mpcore/src/main/cpp/third_party/unicorn/qemu/tcg/tcg-op.c +++ b/mpcore/src/main/cpp/third_party/unicorn/qemu/tcg/tcg-op.c @@ -2867,6 +2867,14 @@ static void gen_ldst_i64(TCGContext *tcg_ctx, TCGOpcode opc, TCGv_i64 val, TCGv // uc_emu_stop (FnvHashAccelHookCb) is a UC_HOOK_CODE hook, where the check is // still emitted. So the per-access check is pure overhead here. // +// VERIFIED 2026-09-19 on a freshly rebooted device, three interleaved pairs, +// load to first OnCarLoaded: +// without the check: 33.42 / 33.10 / 33.32 s mean 33.28 +// with the check: 35.62 / 35.43 / 35.49 s mean 35.51 +// 6.3% faster, ranges completely separate. (The first attempt at this +// measurement produced one usable pair before the device's screen dozed and +// the engine stopped rendering entirely - see the session log.) +// // Kept as a named constant rather than deleted, because this is a vendored // tree: anyone adding a memory hook that calls uc_emu_stop MUST flip this // back, or that stop will be deferred to the next block boundary.