HIGHLIGHT — OPTIMISATION

GameParticles

An optimisation contest: take a naïve real-time particle system and make it as fast as possible without changing a pixel. Final capture: 107.68 ms down to 14.71 ms.

Captures — release build, measured

before after
GameParticles frame loop 7.32x
107.68 ms
14.71 ms

Release build. Contest grading capped at 4.00x — final result nearly doubled the ceiling.

An optimisation contest: everyone gets the same deliberately naïve particle system and the same rule — identical visual output, minimum wall-clock time. The scoring scale maxed out at 4.00x. My final submission ran 7.32x faster than baseline.

The approach

No single trick gets you 7x. The gain came from stacking passes, each verified against the renderer before moving on:

  1. Precision dietdouble math everywhere the original didn’t need it became float, halving bandwidth through the hot loop.
  2. Const-correctness and copy elimination — the baseline copied particle state through every update; references and const let the compiler stop defending against mutation.
  3. std::liststd::vector — the particle store went from pointer-chasing to contiguous iteration; the prefetcher does the rest.
  4. Rule of Big Four — explicit copy/assign/move semantics on the hot types so nothing was constructed by accident.
  5. Object pooling — allocation pulled out of the per-frame path entirely, through a custom pool built on the course’s allocator work.
  6. Dropping the STL where it cost — after measurement, not on principle.
  7. SIMD (SSE4.1) — the endgame: Vect4D and Matrix rewritten on 16-byte-aligned intrinsics, turning four scalar operations into one.

The numbers

CaptureFrame timeSpeedup
Baseline (naïve)107.68 ms1.00x
Final (all passes)14.71 ms7.32x

Every pass was measured in Release against the unchanged rendering output — any visual deviation was a disqualification, so correctness testing was as much of the work as the optimisation itself.

Why it matters

This is the discipline engine teams actually pay for: measure, change one thing, verify, repeat — and know the memory layout story before reaching for intrinsics. The same habits carried directly into the engine and the CUDA work.