Add CMake option to enable/disable performance monitoring

This commit is contained in:
Camden Dixie O'Brien 2025-01-02 17:10:00 +00:00
parent c1dd9cd33a
commit 3952d93bb0
3 changed files with 20 additions and 6 deletions

View File

@ -4,6 +4,7 @@ project(epec-mcu-emulator LANGUAGES C)
option(WERROR "Treat warnings as errors" OFF) option(WERROR "Treat warnings as errors" OFF)
option(SANITIZERS "Enable memory and undefined behaviour sanitizers" OFF) option(SANITIZERS "Enable memory and undefined behaviour sanitizers" OFF)
option(PERFMON "Monitor performance of game code" ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

View File

@ -1,3 +1,6 @@
add_library(engine engine.c) add_library(engine engine.c)
set_default_target_options(engine) set_default_target_options(engine)
target_include_directories(engine PUBLIC include) target_include_directories(engine PUBLIC include)
if(${PERFMON})
target_compile_definitions(engine PRIVATE PERFMON)
endif()

View File

@ -13,6 +13,12 @@
#define VT100_CURSORTOPLEFT "\33[H" #define VT100_CURSORTOPLEFT "\33[H"
#define VT100_CLEAR "\33[2J" #define VT100_CLEAR "\33[2J"
#ifdef PERFMON
#define GETPERF(x) x = SDL_GetPerformanceCounter()
#else
#define GETPERF(x)
#endif
typedef struct { typedef struct {
double freq; double freq;
uint64_t start, evt, update, render; uint64_t start, evt, update, render;
@ -39,10 +45,12 @@ int main(int argc, char *argv[])
void *gamemem = calloc(1, game_conf.memsize); void *gamemem = calloc(1, game_conf.memsize);
game_init(argc, argv, gamemem, renderer); game_init(argc, argv, gamemem, renderer);
#ifdef PERFMON
perf_t perf = { .freq = SDL_GetPerformanceFrequency() / 1000000.0 }; perf_t perf = { .freq = SDL_GetPerformanceFrequency() / 1000000.0 };
uint64_t frame = 0; uint64_t frame = 0;
#endif
while (1) { while (1) {
perf.start = SDL_GetPerformanceCounter(); GETPERF(perf.start);
// Handle all events currently in queue // Handle all events currently in queue
SDL_Event evt; SDL_Event evt;
@ -50,18 +58,19 @@ int main(int argc, char *argv[])
if (game_evthandle(gamemem, &evt) != GAMESTATUS_OK) if (game_evthandle(gamemem, &evt) != GAMESTATUS_OK)
goto quit; goto quit;
} }
perf.evt = SDL_GetPerformanceCounter(); GETPERF(perf.evt);
// Update game state // Update game state
if (game_update(gamemem, interval) != GAMESTATUS_OK) if (game_update(gamemem, interval) != GAMESTATUS_OK)
goto quit; goto quit;
perf.update = SDL_GetPerformanceCounter(); GETPERF(perf.update);
// Render frame // Render frame
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
game_render(gamemem, renderer, SDL_GetTicks64()); game_render(gamemem, renderer, SDL_GetTicks64());
perf.render = SDL_GetPerformanceCounter(); GETPERF(perf.render);
#ifdef PERFMON
// Print performance analysis every 16 frames // Print performance analysis every 16 frames
if ((frame & 15) == 0) { if ((frame & 15) == 0) {
const double evt = (perf.evt - perf.start) / perf.freq; const double evt = (perf.evt - perf.start) / perf.freq;
@ -75,9 +84,10 @@ int main(int argc, char *argv[])
"%10.3f μs\ntotal\t%10.3f μs (%05.2f%%)\n", "%10.3f μs\ntotal\t%10.3f μs (%05.2f%%)\n",
evt, update, render, total, total_pc); evt, update, render, total, total_pc);
} }
// Increment frame counter and present frame
++frame; ++frame;
#endif
// Present frame
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
} }