Record retained extent-frame progress and remaining layout gap
This commit is contained in:
1 parent
035c7f20e8
commit
32151f7f9f
2 files changed
+83
-17
No files matched your search
+75
-16
@@ -423,7 +423,7 @@ The original proposal was implemented by Claude as `5fcace1` on
|
||||
`wip/region-and-placement` in `/home/bob/repos/iris-pr18`. It kept the fraction
|
||||
reference stable but failed five layout cases and three draw-count cases.
|
||||
The first correction is `efb416b`, exact recomposition is `2ed5503`, and the
|
||||
current performance continuation is **`a7307d9`**, pushed to origin's
|
||||
current performance continuation is **`c44bd19`**, pushed to origin's
|
||||
`wip/region-and-placement`, in the isolated checkout
|
||||
`/home/bob/repos/iris-layout-experiment`; **it is not on PR #18**. The original
|
||||
checkout is unchanged. Keep the experiment's build directory separate: Cargo
|
||||
@@ -517,22 +517,24 @@ regression fails with four draws instead of three when the optimization is
|
||||
disabled.
|
||||
|
||||
**Still not ready to replace PR #18.** The prototype does substantially more
|
||||
nested layout work than `e44dea3`, even after removing intermediate placements
|
||||
(seed 1, depth 8):
|
||||
nested layout work than `e44dea3`, even after retaining extent-relative child
|
||||
frames (seed 1, depth 8):
|
||||
|
||||
| phase | widget draws at e44dea3 | current | primitive writes at e44dea3 | current |
|
||||
| --- | ---: | ---: | ---: | ---: |
|
||||
| cold | 369 | 484 | 9635 | 9179 |
|
||||
| cold | 369 | 463 | 9635 | 9179 |
|
||||
| repaint | 1 | 1 | 1 | 1 |
|
||||
| many | 157 | 274 | 4721 | 5873 |
|
||||
| size | 16 | 247 | 106 | 5200 |
|
||||
| many | 157 | 263.1 | 4721 | 5873 |
|
||||
| size | 16 | 240 | 106 | 5200 |
|
||||
| scroll | 2 | 2 | 0 | 0 |
|
||||
| resize | 13 | 292 | 0 | 5730 |
|
||||
| resize | 13 | 278 | 0 | 5730 |
|
||||
|
||||
These are instrumented work counts, not speedups (50 frames per phase except
|
||||
cold, which is one; 578 generated widgets, 191 finally active). Against
|
||||
`2ed5503`, the changes remove 7 widget draws and 525 primitive writes per size
|
||||
frame, and 8 draws and 525 writes per resize frame.
|
||||
cold, which is one; 578 generated widgets, 191 finally active). The
|
||||
measurement-only change at `7601aa2` removed 7 widget draws and 525
|
||||
primitive writes per size frame, and 8 draws and 525 writes per resize frame,
|
||||
relative to `2ed5503`. The extent-relative continuation below skips additional
|
||||
container evaluations but does not reduce primitive writes.
|
||||
|
||||
**Measure cycles as well as instructions** (Bryan, 2026-09-17). The following
|
||||
are whole-process medians from seven alternating before/after runs of direct,
|
||||
@@ -578,7 +580,7 @@ executables under `perf stat -e cycles:u,instructions:u`, seed 1, depth 8,
|
||||
All nine samples per side were retained; before/after cycle ranges do not
|
||||
overlap. No scans or builds ran during measurement. All instrumented work
|
||||
counters match `7601aa2` on all six phases (50 frames, cold once), including
|
||||
the draw and primitive counts in the table above: this reduces the cost of
|
||||
the primitive counts in the table above: this reduces the cost of
|
||||
emitting the repeated glyphs, not the repeated layout evaluations themselves.
|
||||
|
||||
Additional depth-6 fixtures, nine alternating pairs and 4000 frames each:
|
||||
@@ -602,14 +604,71 @@ saved under 0.8% of instructions and no cycles; special-casing equal endpoint
|
||||
fractions in `UiSpan::within` cost 11% cycles and 7% instructions despite still
|
||||
inlining. Keep that hot general composition small.
|
||||
|
||||
**Child frames can now follow the extent without evaluating their container.**
|
||||
`widget_within` accepts the same `DrawRegion::{Frame, Extent}` reference as
|
||||
primitives and masks. `Pad` retains its pixel inset in extent coordinates;
|
||||
`Stack` inherits placement for its sizing child and retains extent-relative
|
||||
frames for its other children. Moving the extent replays those requests through
|
||||
`ask_box`, preserving child alignment and region nodes. This extends the existing
|
||||
inherited-child walk rather than adding a separate layout body or a second cache.
|
||||
It stores a region-bearing relation per extent-following child, so retained
|
||||
child records are larger than the old widget-id-only list.
|
||||
|
||||
Two dependencies stay conservative. Fractional endpoints compose before pixel
|
||||
evaluation, so their bounds cannot in general be pulled back through the extent
|
||||
length alone; those frames still depend on raw placement. Reading a child's
|
||||
fractional report also depends on placement because composing that report into
|
||||
the parent's frame can change its value without changing the child's answer.
|
||||
Pixel-inset frame bounds use the existing exact `Holds::through`.
|
||||
|
||||
**Keep the measured slot when repositioning.** A first trial recomputed it from
|
||||
`active.size`, which is the final draw's report. Text measured narrow and placed
|
||||
wider may report a different height at the latter width; the slot is still the
|
||||
one chosen from measurement. Seed 20/depth 4 caught this. The retained slot is
|
||||
now preserved on axes not explicitly assigned by the parent. A small synthetic
|
||||
width-dependent widget pins the same failure without fonts.
|
||||
|
||||
Against `a7307d9`, seed 1/depth 8 skips 21 draws cold, 10.9 per `many` frame,
|
||||
7 per size frame and 14 per resize frame. Repaint, scroll, and all primitive-write
|
||||
counts are unchanged. Nine alternating pairs of direct uninstrumented release
|
||||
executables under `perf stat -e cycles:u,instructions:u`, including setup:
|
||||
|
||||
| phase | median cycles before → after (billions) | median instructions before → after (billions) |
|
||||
| --- | ---: | ---: |
|
||||
| size (2000 frames) | 4.0819 → 4.0714 | 10.4107 → 10.4017 |
|
||||
| resize (2000 frames) | 4.8108 → 4.7237 | 12.1854 → 11.9252 |
|
||||
| many (2000 frames) | 4.7918 → 4.7787 | 12.0925 → 12.0567 |
|
||||
| repaint (1,000,000 frames) | 2.6701 → 2.6851 | 6.0175 → 6.0195 |
|
||||
| scroll (300,000 frames) | 2.6296 → 2.6273 | 6.5025 → 6.5817 |
|
||||
|
||||
Only resize establishes a cycle improvement: **1.8%**, with nonoverlapping sample
|
||||
ranges, and 2.1% fewer instructions. Every other phase's cycle ranges overlap;
|
||||
scroll uses 1.2% more instructions. All samples were retained and no scans or
|
||||
builds ran during measurement. This is a small reduction in work, not closure of
|
||||
the main gap.
|
||||
|
||||
Verification: workspace formatting, clippy with `layout-diagnostics`, tests
|
||||
(104 suite tests, 21 core tests), exact release scans of 2000 seeds/depth 4 and
|
||||
1000/depth 6, the shrinker over 400 trees/depth 5, and a debug scan of 120
|
||||
seeds/depth 4 with assertions enabled.
|
||||
The new no-redraw test checks nested padding/stacks, fixed child
|
||||
alignment, primitives, masks, and region nodes; restoring the old container
|
||||
calls makes it fail with three draws instead of two. Additional tests cover
|
||||
fractional reports and numeric dependencies. All five reference renders match
|
||||
`a7307d9` pixel for pixel at 1920x1200, and the resized 900x1200 `tabs` matches a
|
||||
cold render there. The GPU probe reports Venus on the RX 7900 XT.
|
||||
|
||||
**The remaining gap has not been established as an unavoidable correctness
|
||||
cost.** A temporary failure trace of one frame on seed 1, depth 8 counted
|
||||
39/108 failed reuse attempts in size, 65/151 in resize, and 45/109 in many
|
||||
cost.** Before the extent-relative change, a temporary failure trace of one
|
||||
frame on seed 1, depth 8 counted 39/108 failed reuse attempts in size, 65/151 in resize, and 45/109 in many
|
||||
where only the raw placement snapshot differed: both numeric frame and extent
|
||||
ranges still held. Containers read that snapshot to construct child positions,
|
||||
so discarding the check would be wrong; a way to retain those child positions
|
||||
relative to the extent is the next protocol question. There is also necessary
|
||||
width-dependent work: the hot text at widget 199 visits 68 px and 89.53613 px
|
||||
so discarding the check would be wrong. Padding and stacks now retain their
|
||||
extent-relative child frames, but `Span` still constructs its mixed-reference
|
||||
slots from a raw placement read: along the row, child fractions refer to the
|
||||
frame while cursor positions and leftover room refer to the extent. Retaining
|
||||
those expressions without changing their fixed-point evaluation order is the
|
||||
next protocol question. There is also necessary width-dependent work: the hot text at widget 199 visits 68 px and 89.53613 px
|
||||
and reports different heights (316.80078 and 228.80078). It is evaluated
|
||||
repeatedly at those widths, so that fact alone does not justify all the repeats.
|
||||
|
||||
|
||||
Reference in new issue
Block a user