3.1 KiB
Profile optimized sprite builds instead of unoptimized debug code
Summary
make flame-build currently compiles the selected example with -debug but
without an optimization mode:
odin build examples/$(FLAME_EXAMPLE) -collection:pkg=. -out:$(FLAME_BIN) -debug
This makes the flamegraph useful for debugging but misleading for performance decisions. The current profiles largely describe code that will disappear or be inlined in an optimized build.
Evidence
The two checked-in crowd profiles were captured from this unoptimized binary.
They report:
engine::draw_sprite: 9.56% and 12.22% self timeengine::to_clip: 5.33% and 5.51% self timeengine::sprite_feet_quad: 3.98% and 3.30% self time- Additional time in string hashing/map lookup, bounds checks, and dynamic array append helpers
A CPU-only benchmark using the real draw_sprite, real baked toad metadata,
preallocated draw list, changing sprite positions, and two million draws per
trial produced:
| Build | Median time per draw | Trials |
|---|---|---|
-debug (current Makefile behavior) |
192.560 ns | 7 |
-debug -o:speed |
19.154 ns | 7 |
The optimized build is about 10.1x faster without an engine code change.
An end-to-end 128-sprite benchmark on SDL 3.4.12 with Lavapipe showed only a small full-frame difference (median 2.486 ms debug versus 2.447 ms optimized) because software GPU/driver work dominated. This does not invalidate the CPU result; it shows why CPU queue time and full-frame time must be reported separately.
Environment:
- Odin
dev-2026-05-nightly:ea5175d(the version pinned by CI) - SDL 3.4.12
- Linux x86-64
Suggested fix
Compile profiling binaries with optimization while retaining symbols:
FLAME_ODIN_FLAGS ?= -debug -o:speed
flame-build:
odin build examples/$(FLAME_EXAMPLE) \
-collection:pkg=. \
-out:$(FLAME_BIN) \
$(FLAME_ODIN_FLAGS)
Keeping the flags configurable allows an explicitly unoptimized diagnostic run without making it the performance default.
Example usage:
# Representative performance profile: optimized code with debug symbols.
make flame FLAME_EXAMPLE=crowd
# Explicitly profile unoptimized code when investigating debug-only behavior.
make flame FLAME_EXAMPLE=crowd FLAME_ODIN_FLAGS="-debug -o:none"
Reproduce the isolated build-mode comparison with the committed CPU harness:
make perf-draw PERF_ODIN_FLAGS="-debug -o:none"
make perf-draw PERF_ODIN_FLAGS="-debug -o:speed"
Both runs print the Git commit, Odin version, compiler flags, every trial, and the median nanoseconds per draw.
Consider applying an explicit optimization mode to performance-oriented example
runs as well. Plain odin run currently uses Odin's unoptimized default.
Acceptance criteria
make flame-buildproduces an optimized binary with debug symbols.FLAME_ODIN_FLAGScan override the default for diagnostic builds.make checkandmake testcontinue to pass.- A new
crowdprofile records the exact compiler flags in its report or accompanying documentation. - Performance conclusions distinguish CPU
draw_spritecost from complete frame/GPU submission cost.