Skip to content

Make the sequencer pixel generator cheaper on opened borders - #326

Merged
highbyte merged 1 commit into
feature/cpu-cycle-enginefrom
feature/c64-vic2-sequencer-open-border-perf
Sep 10, 2026
Merged

Make the sequencer pixel generator cheaper on opened borders#326
highbyte merged 1 commit into
feature/cpu-cycle-enginefrom
feature/c64-vic2-sequencer-open-border-perf

Conversation

@highbyte

Copy link
Copy Markdown
Owner

Summary

The sequencer pixel generator runs its per-cycle pipeline over every cycle of every line, so a frame that opens the vertical border, where the whole line is output, is about twice the work of a text screen. On a sprites-only demo that does so the sequencer rendered at three times the legacy generator's cost. Four changes to the generator, none of which change its output:

  • Identical-block cache: a cycle whose fetched bytes, mode and pipeline state (shift register, its matrix and colour, pixel value, pair phase, XSCROLL load pixel) equal the previous block's copies its eight foreground/background codes and takes that block's end state. Covers the idle byte across an opened border, runs of identical cells, and blank cells under any XSCROLL, which the aligned fast path never reached.
  • The line's colour resolve copies such blocks' colours instead of looking them up, via a per-line serial mark.
  • Sprite rows are decoded into a buffer and written as runs through the bulk pixel delegates instead of a delegate call per pixel.
  • The fetch ring's slots are derived instead of taken as three modulos per cycle.

Validation

  • Timing on this machine (MacBook Air M1, .NET 10.0.401, quiet, headless probe running "For Your Sprites Only" frames 400-1000, medians of alternating repeats): sequencer 1587 → 1172 µs per frame with per-line sprites on, 1404 → 1025 off; legacy generator 826 / 725; CPU and VIC-II alone 404.
  • Frame benchmark RenderOnly rows, this branch vs the integration branch alternating: 474-477 vs 476-489 without sprites, 491-494 vs 495-496 with eight, i.e. level. An earlier version of the cache had cost the text screen 7-10%; packing the compare into one key and using direct copies removed that.
  • Output identical: 113 VICE test programs across ten suites with the same 18 known differences as before, 467 C64 tests, full suite 2935 passed, Commando and Giana Sisters byte-identical to the integration branch, desktop and browser apps build clean.
  • SonarCloud branch analysis clean at Major and above.

The sequencer runs its per-cycle pipeline over every cycle of every line, so a
frame with the vertical border opened is about twice the work of a text screen.
Four changes to the generator keep that cheap: a block whose fetched bytes, mode
and pipeline state equal the block before repeats its eight codes by copy (the
idle byte across an opened border, runs of identical cells, blank cells under
any XSCROLL), the line's colour resolve copies such blocks as well, sprite rows
are decoded once and written as runs through the bulk pixel delegates instead of
a delegate call per pixel, and the fetch ring's slots are derived instead of
taken as modulos per cycle.

On a sprites-only demo that opens the border the sequencer drops from 1587 to
1172 microseconds per frame with per-line sprites on and from 1404 to 1025 off
on this machine; the text-screen benchmark is level with the integration branch.
Output is unchanged: VICE test programs, game snapshots and all tests identical.
@sonarqubecloud

Copy link
Copy Markdown

@highbyte
highbyte merged commit 8e73e00 into feature/cpu-cycle-engine Sep 10, 2026
10 checks passed
@highbyte
highbyte deleted the feature/c64-vic2-sequencer-open-border-perf branch September 10, 2026 19:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant