Published by Sean Carr
First Vulkan Wins: Four Fixes Worth 2x to 900x
A CPU compositor, a write-combined readback buffer, a debug build flag, and a per-frame bounds walk, each found by measuring before cutting.
At a Glance
CPU compositor to GPU, per frame
about 900x
GPU render path for the playable beach: about 1650 ms/frame (about 0.6 FPS) on the CPU software composite to about 1.8 ms/frame on the GPU, a reduction of about 900x. One CPU core had been rasterizing a 36-primitive palm every frame while the GPU sat idle.
Readback memory type
about 74x
Readback memory type: CPU reads from a write-combined memory type ran at about 137 MB/s, about 27 ms/frame. Switching to a host-cached type measured about 27,400 us/frame to about 368 us/frame (about 74x) on an RTX 5080 at 1920x1080, with byte-identical captured frames.
Compiler optimization (/O2)
2.3x
Compiler optimization: the canonical build had been compiling without optimization (MSVC default /Od). Enabling /O2 cut startup load from 13.4 s to 5.8 s (2.3x) and per-frame render by 1.8x, with determinism golden captures byte-identical.
Shadow-fit bounds memo
about 12-20x
Shadow-fit bounds memo: the shadow fit re-transformed about 59M vertices per frame. Caching per-item world bounds cut whole-frame time from about 391-407 ms/frame to about 20-33 ms/frame (about 12-20x), with the light matrix hash bit-identical across cached and uncached paths.
| Telemetry Metric | Measured Value | Context & Observability |
|---|---|---|
| CPU compositor to GPU, per frame | about 900x | GPU render path for the playable beach: about 1650 ms/frame (about 0.6 FPS) on the CPU software composite to about 1.8 ms/frame on the GPU, a reduction of about 900x. One CPU core had been rasterizing a 36-primitive palm every frame while the GPU sat idle. |
| Readback memory type | about 74x | Readback memory type: CPU reads from a write-combined memory type ran at about 137 MB/s, about 27 ms/frame. Switching to a host-cached type measured about 27,400 us/frame to about 368 us/frame (about 74x) on an RTX 5080 at 1920x1080, with byte-identical captured frames. |
| Compiler optimization (/O2) | 2.3x | Compiler optimization: the canonical build had been compiling without optimization (MSVC default /Od). Enabling /O2 cut startup load from 13.4 s to 5.8 s (2.3x) and per-frame render by 1.8x, with determinism golden captures byte-identical. |
| Shadow-fit bounds memo | about 12-20x | Shadow-fit bounds memo: the shadow fit re-transformed about 59M vertices per frame. Caching per-item world bounds cut whole-frame time from about 391-407 ms/frame to about 20-33 ms/frame (about 12-20x), with the light matrix hash bit-identical across cached and uncached paths. |
Published by Sean Carr
View & print executive brief version →Executive Summary & Core Finding
In the first week the Atlas Engine rendered its playable beach scene through Vulkan, four separate fixes moved the frame or startup time by large factors. The biggest was moving a scene off a single-core CPU compositor onto the GPU, cutting per-frame cost from about 1650 ms to about 1.8 ms. Each fix was checked for bit-identical or byte-identical output before it shipped.
Method
Data collected Jul 24-26, 2026; written up October 2026.
Four commits on the Atlas Engine (C++20, Vulkan) between July 24 and July 26, 2026.
Each change was measured with the engine's own timing hooks on the development workstation, A/B'd against the old path through an environment switch where one existed, and gated on determinism or byte-identity checks.
Hardware is stated in the commit record only for the readback fix (RTX 5080, 1920x1080 window).
Run counts per measurement are not recorded beyond what is listed below.
What We Measured
Four fixes in the first week of Vulkan rendering
CPU compositor to GPU, per frame
about 900x
GPU render path for the playable beach: about 1650 ms/frame (about 0.6 FPS) on the CPU software composite to about 1.8 ms/frame on the GPU, a reduction of about 900x. One CPU core had been rasterizing a 36-primitive palm every frame while the GPU sat idle.
Readback memory type
about 74x
Readback memory type: CPU reads from a write-combined memory type ran at about 137 MB/s, about 27 ms/frame. Switching to a host-cached type measured about 27,400 us/frame to about 368 us/frame (about 74x) on an RTX 5080 at 1920x1080, with byte-identical captured frames.
Compiler optimization (/O2)
2.3x
Compiler optimization: the canonical build had been compiling without optimization (MSVC default /Od). Enabling /O2 cut startup load from 13.4 s to 5.8 s (2.3x) and per-frame render by 1.8x, with determinism golden captures byte-identical.
Shadow-fit bounds memo
about 12-20x
Shadow-fit bounds memo: the shadow fit re-transformed about 59M vertices per frame. Caching per-item world bounds cut whole-frame time from about 391-407 ms/frame to about 20-33 ms/frame (about 12-20x), with the light matrix hash bit-identical across cached and uncached paths.
What We Think It Suggests
- Early in an engine's life, the largest wins tend to be configuration and placement mistakes rather than algorithm problems: work on the wrong processor, memory of the wrong type, or a debug compiler setting left on. None of these four required a new algorithm.
- Pairing every speedup with a byte- or bit-identity check made it cheap to accept large changes quickly, because a wrong result would have shown up as a hash mismatch rather than as a subtle visual drift.
Limits
- These are single-scene measurements of an early, small scene; later scenes are much heavier and the ratios do not transfer.
- Most commits report approximate values (with ~) and do not record run counts, percentiles, or hardware; only the readback fix names the GPU.
- The 900x and 12-20x figures compare against paths that were unusually slow, so they describe how bad the starting point was more than how fast the engine is.
Detailed Analysis & Field Observations
In the first week the Atlas Engine rendered its playable beach scene through Vulkan, four separate fixes moved the frame or startup time by large factors. The biggest was moving a scene off a single-core CPU compositor onto the GPU, cutting per-frame cost from about 1650 ms to about 1.8 ms. Each fix was checked for bit-identical or byte-identical output before it shipped.
Data collected Jul 24-26, 2026; written up October 2026.