From 5a6b2c1540bd77cc3395bf2eef65115e5cef2716 Mon Sep 17 00:00:00 2001 From: megboyzz Date: Wed, 23 Sep 2026 00:42:55 +0300 Subject: [PATCH] docs: record the first correct in-race frame rate Measured on both hosts, with the method and the reason a median is the wrong statistic for the Pixel 6a (bimodal 60/30 - the median sits in the upper lobe and reports 59.8 where the mean is 39.5). Also retires the old "51 fps" from task #61: it was not measured in a race and is not comparable. That is the second time a figure from elsewhere in the game was nearly quoted as in-race performance, so it is written down plainly. The consequence is a priority change - the 6a misses the frame budget by a few percent, so #63 and #64 are worth more than their profile shares suggest, and the hot path has very little margin left to spend on new work. Co-Authored-By: Claude --- docs/ARM64_TRANSLATION_LAYER.md | 56 +++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/docs/ARM64_TRANSLATION_LAYER.md b/docs/ARM64_TRANSLATION_LAYER.md index d6fdc69..0853da7 100644 --- a/docs/ARM64_TRANSLATION_LAYER.md +++ b/docs/ARM64_TRANSLATION_LAYER.md @@ -3635,3 +3635,59 @@ One real caveat: the flat guest mapping (task #61, the 1.24x win) exists only in `tcg/aarch64`. An x86_64 host silently falls back to the software MMU. That is recorded in a comment next to the `abiFilters` line so the next person does not read x86 numbers as if the same optimisation were in play. + +## 2026-09-22 - the first correct in-race frame rate, on two hosts + +Until now no in-race frame rate had ever been measured properly; the log ring +kept wrapping before a race finished. Every speed figure in this document +before this entry was taken somewhere else in the game. In particular the +"51 fps" quoted for the flat-mapping A/B (task #61) was **not** measured in a +race and must not be compared against anything below. This repeats an error +already made once here, when a "60 fps" reading turned out to be the results +screen. + +### Method + +`dumpsys SurfaceFlinger --latency` on the game's own BLAST layer, six +back-to-back samples, deduplicated by actual-present timestamp, then look at +the **distribution** of intervals rather than an average. A screenshot is +taken with every capture - without it there is no way to know a menu was not +measured instead of a race, which is exactly how the old numbers went wrong. + +### Pixel 6a, in race (60 Hz, 16.67 ms), 140 frames + + median 16.72 ms (59.8 fps) <- misleading, do not quote + mean 25.32 ms (39.5 fps) <- the honest figure + p95 33.38 ms, worst 66.56 ms + + 1 vsync (60 fps) 74 frames + 2 vsync (30 fps) 61 frames + 3 vsync (20 fps) 3 frames + 4 vsync (15 fps) 2 frames + +The distribution is bimodal. The phone very nearly makes 60 and misses on +roughly half the frames, dropping exactly to 30. The median sat inside the +upper lobe and reported 59.8, which is why a median is the wrong statistic +here and the mean is quoted instead. + +### WayDroid x86_64, in race (144 Hz, 6.944 ms), 128 frames + + median 34.72 ms (28.8 fps) + mean 35.05 ms (28.5 fps) + p95 41.68 ms, worst 48.61 ms + +Every frame lands on exactly five vsync periods. Slower than the phone and +visibly smoother, because steady beats fast-but-uneven - the user described it +as "очень плавно" before any of this was measured, and the numbers agree. +GLThread sits at 96.7% of one core out of sixteen: CPU-bound in translation, +not GPU-bound. + +### Why this changes the priorities + +The 6a misses the 16.67 ms budget by a few percent. So a 10-15% CPU win does +not buy "a few more fps" - it flips those 61 two-vsync frames back to one, and +the phone lands on a stable 60. That makes task #63 (VFP on host FP instead of +softfloat, ~9% of profile) and task #64 (`helper_lookup_tb_ptr`, 12.18%) worth +far more than their profile shares suggest, and it means anything new added to +the hot path - the multiplayer hooks included - is spending a margin that is +currently only a few percent wide.