Skip to content

Put It on the Clock

Choose a question, measure comparable work, and check that a faster result still does the right job.

  • Foundations

Unit 4 separated control over instructions from a promise of speed. Now we need evidence: which work takes time, what could change, and whether the change helps the game we want to make.

Count work, then measure time

Our toy translator lets us count lookups and additions. It has no specified processor or clock, so those counts cannot tell us how many milliseconds it takes. Two instructions need not take equal time, and a shorter listing need not run faster.

Moving translation out of a loop can remove repeated work. The resulting program still performs calculations, accesses memory and may wait for hardware. Its choice of algorithm and data representation matters too. Assembly makes many of those choices explicit; it does not guarantee the best choices.

Ask a question we can answer

Suppose a busy scene responds late. “Make everything faster” is hard to test. “Can we avoid drawing an intermediate position while keeping both collision checks?” gives us one change and a behaviour to preserve.

Before comparing two versions, record:

  • The job: the same starting state, inputs and required result.
  • The boundary: where timing starts and stops, including any setup we intend to count.
  • The clock: its units, resolution and the machine or emulator configuration.
  • The checks: what must remain correct after the change.

Keep the original version. Measure it, change one relevant thing, then repeat the same workload and correctness checks. A small program may need only a short note.

Averages can hide the problem

Here are invented measurements for a prediction exercise, not results from a course game. Suppose each update must finish within 12 milliseconds:

Update Version A Version B
1 8 ms 10 ms
2 8 ms 10 ms
3 8 ms 10 ms
4 16 ms 10 ms

Predict the average for each version. Which meets the deadline on every recorded update? What would we still need to check before choosing it?

Compare the average with the slow update

Both average 10 milliseconds. A misses the deadline once; B meets it in these four observations. If the late update caused our glitch, the average concealed what we needed to investigate.

We still need to check that B performs the required work and test other relevant scenes. Four measurements do not prove a worst-case bound. A version that skips a collision test may be quicker but change the game.

An optional route into a real game

When we reach Spectrum assembly, Meteor Storm unit 20 and unit 21 provide an existing comparison. Unit 21 avoids an intermediate redraw during boost while retaining both simulation steps and contact checks. We do not need to understand its assembly yet to identify the question it investigates.

For a short observation, use the two lessons’ embedded experiments, restore each checkpoint, launch with Space, hold Space for boost and inspect frame_delta. Keep the same steering intention and stop after a short passage. Record the checkpoint, controls and values we actually saw; a different route or early crash changes the workload. This is an exploratory comparison, not a controlled benchmark.

That byte records the difference between the game’s interrupt counts at successive outer-loop samples. It is not the number of simulation steps, a browser frame time or a measurement of input delay. The game deliberately waits for alternate frame counts; a value above one is not automatically a fault. Unit 21 explains the expected cadence and links it to the rendering change.

The browser inspector samples values and can miss an unusual update. Unit 21’s existing native verification records a keyboard-driven passage; it provides stronger evidence for that passage than a glance at the display. Neither observation proves every possible run. This route reuses an existing experiment; we are not required to write a new profiler or compare BASIC with assembly here.

Know what the clock measures

A machine lesson must identify an available counter, timer or emulator facility and explain how to read it. We cannot assume every machine offers the same BASIC clock variable, or even the same language. A counter can wrap; a coarse clock can report zero for work that still took time.

Guest time describes the program on the emulated machine. Host time describes how long our present-day computer spends running the emulator and presenting its output. A slow browser does not by itself show that the original program used more guest cycles. Keep those measurements separate.

Measuring also costs work. Printing a value inside every update can change the behaviour we are investigating. Use the same instrumentation for a comparison, state its limits, and check the result without it when practical.

Writing assembly does not remove the need to check our tools or understanding. The assembler, emulator and hardware documentation can all be part of the evidence; none becomes infallible because we wrote the instructions ourselves.

What we’ve learnt

  • Counted operations and measured time answer different questions.
  • Compare a named workload and preserve its required behaviour.
  • Look for slow updates and missed deadlines, not just an average.
  • Name the clock and distinguish guest measurements from host performance.
  • Explain the change, then measure again; a lower number alone is not completion.

Where this leaves us

We have used a small model to connect source text with instructions. Real languages and machines add details, and the machine lessons introduce them where they matter. Choose a route from Systems: BASIC and assembly offer different ways into making games. Neither needs a universal speed contest to justify learning it.