kobodl/prof.cpp
Ville Lindholm 869056c5d2
Phase 0: profiling scaffolding for DOD refactor
Adds a tiny zone-based profiler (prof.{h,cpp}) enabled via KOBO_PROF=1.
Instruments run_game with zones for myship.move, enemies.move (split into
realize and move_pass), hit_structure, and hit_bolt. Adds KOBO_STRESS=N
to keep the enemy pool topped up with rocks for stable per-frame timing.

Why: the entity/render pipeline refactor in BENCH.md needs a comparable
baseline before any layout changes. Without a stress workload the natural
gameplay enemy count is too noisy to compare across commits.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-29 13:31:31 +03:00

42 lines
1.2 KiB
C++

#include "prof.h"
prof_zone_t prof_zones[PROF_MAX_ZONES];
int prof_nzones = 0;
int prof_enabled = 0;
uint64_t prof_frame_count = 0;
extern "C" void prof_init(void)
{
const char *e = getenv("KOBO_PROF");
prof_enabled = (e && *e && *e != '0') ? 1 : 0;
if (prof_enabled)
fprintf(stderr, "[prof] enabled (dump every %d frames)\n",
PROF_DUMP_EVERY_FRAMES);
}
extern "C" void prof_dump(FILE *f)
{
if (!prof_enabled) return;
fprintf(f, "[prof] frame=%llu zones=%d\n",
(unsigned long long)prof_frame_count, prof_nzones);
for (int i = 0; i < prof_nzones; ++i) {
prof_zone_t *z = &prof_zones[i];
double ns_per_call = z->calls ? (double)z->total_ns / (double)z->calls : 0.0;
double total_ms = (double)z->total_ns / 1.0e6;
fprintf(f, " %-28s calls=%-10llu total_ms=%-10.3f ns/call=%.1f\n",
z->name,
(unsigned long long)z->calls,
total_ms,
ns_per_call);
}
fflush(f);
}
extern "C" void prof_frame_tick(void)
{
if (!prof_enabled) return;
++prof_frame_count;
if (prof_frame_count % PROF_DUMP_EVERY_FRAMES == 0)
prof_dump(stderr);
}