Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 41 additions & 17 deletions plan/todo/conducted-show-frame-cost.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ deployment.
Two expensive scenes therefore land on the same frame at every seam.
Worst crossfade per show, 6,660 lights (4A-37), this box:

| show | main | after the arcs work |
|---|---|---|
| `koln` | 46.8 ms | 40.0 ms |
| `apollo` | 32.8 ms | 31.4 ms |
| `promises` | 53.2 ms | 51.9 ms |
| `nocturne` | ~42–47 ms | unchanged (not edited) |
| show | before either change | now (both merged) | worst seam is |
|---|---|---|---|
| `koln` | 31.8 ms | **31.9 ms** | `coming-to-rest` (NoiseGlow + Motif) |
| `apollo` | 34.5 ms | **32.9 ms** | `matta` (AuroraVeils) |
| `promises` | 54.1 ms | **50.2 ms** | `answer` (AuroraVeils into AuroraVeils) |
| `nocturne` | 42–46 ms | **41.7 ms** | `deep-sea` (NoiseGlow + Starfield) |

Repeat runs vary by a few ms; the *ranking* of seams is stable, the
individual figures less so. Governor `performance`, 6,660 lights.

A 30 fps frame is 33.3 ms. Steady-state scenes are fine — the same
shows sit at 10–16 ms median — so this is a seam-only stall lasting as
Expand All @@ -32,11 +35,31 @@ octaves).

## What has already been done

Nothing structural. Two local mitigations in `koln`, both cheap and
both visible in the table above: the ballad's candle `count` is 52
rather than 72 (cost is linear in `count`, and its three scenes are the
one place in the repertoire where two `Candles` render at once), and
the house-lights floor under Part IIc's stars runs at `octaves=2`.
**Option 3 is done** (PR #43). `Candles` no longer evaluates its whole
`n_lights x count` matrix: the light–flame pairs that carry any light
are found once, cached on a content fingerprint, and the render walks a
flat pair list. `Candles()` went 38.0 -> 3.7 ms, and nocturne's two
candle seams went from 33–46 ms to under 23 — they are no longer
anywhere near the worst thing in that show.

It did not solve the problem, and was never going to: `promises` has no
candles in it at all. What it did was remove one cause completely.

Two local mitigations in `koln` also stand: the ballad's candle `count`
is 52 rather than 72, and the house-lights floor under Part IIc's stars
runs at `octaves=2`.

## Where that leaves it

`koln` (31.9 ms) and `apollo` (32.9 ms) now fit inside a 30 fps frame,
`apollo` only barely. `promises` (50.2 ms) and `nocturne` (41.7 ms) do
not, and both are bounded by `AuroraVeils` and `NoiseGlow` seams that no
amount of candle work touches.

The remaining options are 1, 2 and 4 below. **Option 1 is the only one
that covers `promises`**, because the problem there is two expensive
scenes of the same kind blended together, not one primitive being
wasteful.

## Options, roughly in order of appeal

Expand All @@ -52,11 +75,10 @@ the house-lights floor under Part IIc's stars runs at `octaves=2`.
cheap (both sides light) or expensive, and keep expensive-to-
expensive seams short. Manual, but it is what the `koln` ballad now
does by hand.
3. **Make `Candles` cheaper.** The `(n, count)` pool matrix is the
single largest term in the repertoire. Candles beyond ~25° of a
light contribute nothing; a neighbour list computed once per
geometry (memoized on a content fingerprint, like `SmallPlanet`'s
statics) would turn it into a sparse gather.
3. ~~**Make `Candles` cheaper.**~~ Done, PR #43 — see above. The
approach (neighbour list memoized on a content fingerprint, like
`SmallPlanet`'s statics) transfers directly to any other primitive
with per-entity pools, should one turn up.
4. **Accept it and drop frames at seams.** The playout queue on the
board absorbs a few late frames; a 10–30 s stretch at ~20 fps is
not nothing, but it is a crossfade, and it is where the eye is
Expand All @@ -67,4 +89,6 @@ the house-lights floor under Part IIc's stars runs at `octaves=2`.
None of this has been measured on the deployment box under load, only
on the pattern render in isolation — no codec, no serial, no viewers.
The real question is what `luminary play` does at a seam with six
boards attached, and that has not been run.
boards attached, and that has not been run. Until it has, even the two
shows that now fit a 30 fps frame fit it *with nothing else running*,
which is not the condition they will be played in.
Loading