iris bench: the fling clock, the frame ask, and a report that says what it measured (ai-app-2 42d54ee)

iris APK only; the Compose one is unchanged. Iris reported stuttering
when flinging that is much harder to notice with a finger on the scroll.

Two of the four findings are the report rather than the renderer: the
blocking swapchain acquire was counted as iris's CPU time, and nothing
could say a frame was never produced (`late` is cost, not cadence). The
report now splits every phase into build/acquire/submit and carries a
`missed vsyncs` count.

The two real ones are the frame loop: it asked for its next frame at the
end of the callback, so a frame past the vsync boundary cost a second
one, and the fling was advanced on the wall clock rather than the vsync
the callback carries -- which is the asymmetry with a finger drag, whose
positions come from the finger's own timestamps.

Also opt-level "s" -> 3 for the Android build: p90 0.15ms -> 0.09ms of
iris's own per-frame work, for 1.8 MB of APK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-09-09 00:50:48 -04:00
1 parent 5efa866727
commit ff88052a5c
2 files changed
+50 -1

No files matched your search

+50 -1
View File
@@ -11,7 +11,56 @@ no enrolment and no permissions.
The rest of this file is the runbook that was delivered with the APKs.
**2026-09-08 (newest): nothing on the transcript is unbounded any more,
**2026-09-09 (newest): the fling. iris APK only** -- rebuilt from ai-app-2
`42d54ee`; the Compose one is unchanged from 2026-09-08.
You reported stuttering when flinging that is much harder to notice with
a finger on the scroll. Four things came out of it, and **two of them
were the report rather than the renderer** -- so read the new report
before reading the old numbers against it.
- **The swapchain wait was being counted as iris's CPU time.** The call
that hands back an image to draw into *blocks* until the compositor
frees one, and it was inside the span the report called `cpu_p50`. An
app comfortably ahead of the display spends most of every frame there,
so a perfectly healthy fling read as several milliseconds of iris being
slow. Each phase now says `build / acquire / submit` separately, and
only `build` is work.
- **Nothing could say a frame was never produced.** `late` counts frames
that *cost* more than a budget -- but a late frame still appears on the
next refresh, while a frame that never happens leaves the previous one
on screen twice, and that is what a stutter is. Every phase now carries
`missed vsyncs`. That is the number to watch.
- **iris asked for its next frame at the end of the frame callback**, and
Android schedules that for the next refresh *after the call* -- so any
frame whose work ran past the boundary registered too late and got the
refresh after it. One frame over budget silently cost a second one.
Your fling phase ran at 103fps on a 120Hz screen, which is the shape
that makes. It asks first now.
- **The fling was advanced on the wall clock, not on the vsync the
callback carries.** Frames are shown on an even cadence whichever clock
computed them, so sampling the coast curve at "whenever the callback got
to run" moves the transcript by an uneven distance every frame -- with
no frame late enough to appear in any percentile. **This is most likely
the thing you were seeing**, and it explains why a finger on the screen
doesn't have it: a drag's positions come from the finger's own
timestamps and never went through that clock.
Also `opt-level` for the Android build: it was tuned for size (`"s"`),
which costs a renderer its loop vectorisation. At `3`, iris's own
per-frame work over the same warm fling goes from p90 0.15ms / p99 0.42ms
to p90 0.09ms / p99 0.26ms. The APK grows 9.7 -> 11.5 MB; say if you'd
rather have the size.
**What is worth reporting back**: whether the fling *feels* smoother with
a finger, and the `fling:` block's frame count and `missed vsyncs`. If the
count is near 120 x its seconds and `missed` is small, the loop is fixed;
if `missed` is still large, the cause is elsewhere and the new split says
where. The CPU side is already known not to be it -- a warm fling is p99
0.26ms of layout, with only one frame in six laying anything out.
**2026-09-08: nothing on the transcript is unbounded any more,
and both APKs are new.** Rebuilt from ai-app-2 `afbc2ad`. This one has
things to look at, unlike the last.
Binary file not shown.