From 7dc2952b8d567ab7b37f40089a84fe13538d06f7 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Tue, 3 Jul 2018 20:08:52 +0100 Subject: [PATCH] Start stubbing out profiling utils --- GL/draw.c | 3 +++ GL/profile.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++ GL/profile.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 GL/profile.c create mode 100644 GL/profile.h diff --git a/GL/draw.c b/GL/draw.c index e1e861b..7e1cc95 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -3,6 +3,7 @@ #include "../include/gl.h" #include "../include/glext.h" #include "private.h" +#include "profile.h" typedef struct { const void* ptr; @@ -192,6 +193,8 @@ inline void transformNormalToEyeSpace(GLfloat* normal) { static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum type, const GLvoid* indices) { + TRACE_START(); + static GLfloat normal[3] = {0.0f, 0.0f, -1.0f}; static GLfloat eye_P[3]; static GLfloat eye_N[3]; diff --git a/GL/profile.c b/GL/profile.c new file mode 100644 index 0000000..8fd22a0 --- /dev/null +++ b/GL/profile.c @@ -0,0 +1,68 @@ +#include "profile.h" + +Profiler __profiler; + +void profiler_init() { + __profiler.trace_count = 0; +} + +static uint32_t time_now_in_ms() { + return timer_us_gettime64() / 1000; +} + +static int compare(const void* trace1, const void* trace2) { + Trace* t1 = (Trace*) trace1; + Trace* t2 = (Trace*) trace2; + return (t1->total_time < t2->total_time) ? -1 : (t2->total_time < t1->total_time) ? 1 : 0; +} + +void profiler_dump(uint32_t ms) { + static uint32_t time_since_last = time_now_in_ms(); + + uint32_t now = time_now_in_ms(); + + if((now - time_since_last) >= ms) { + qsort(__profiler.traces, __profiler.trace_count, sizeof(Trace), compare); + + fprintf(stderr, "Function\t\t\t\tTotal Time\t\t\t\tBreakdown\n"); + for(uint8_t i = 0; i < __profiler.trace_count; ++i) { + Trace* trace = __profiler.traces + i; + fprintf(stderr, "%s\t\t\t\t%dms\n", trace->name, trace->total_time); + + for(uint8_t j = 0; j < trace->max_checkpoints; ++j) { + fprintf(stderr, "\t\t\t\t\t\t\t\t%d: %dms\n", trace->checkpoints[j].total_time); + } + + fprintf(stderr, "\n\n"); + } + + time_since_last -= ms; + } +} + +void profiler_register_trace(Trace* trace, const char* func_name) { + __profiler.traces[__profiler.trace_count++] = trace; + + trace->calls = 0; + trace->max_checkpoints = 0; + trace->total_time = 0; + trace->start = 0; + + strncpy(trace->name, func_name, 128); +} + +void profiler_trace_start(Trace* trace) { + trace->start = time_now_in_ms(); + trace->calls++; +} + +void profiler_trace_checkpoint(Trace* trace, int counter) { + uint32_t now = time_now_in_ms(); + uint32_t checkpoint_time = (now - trace->start); + + trace->total_time += checkpoint_time; + trace->start = now; + + trace->checkpoints[counter].total_time + checkpoint_time; + trace->checkpoints[counter].calls++; +} diff --git a/GL/profile.h b/GL/profile.h new file mode 100644 index 0000000..e9695ef --- /dev/null +++ b/GL/profile.h @@ -0,0 +1,74 @@ +#ifndef PROFILE_H +#define PROFILE_H + +#include +#include "../containers/aligned_vector.h" + +/* USAGE: + * + * profiler_init(); + * + * void my_func() { + * TRACE_START(); + * + * ... + * + * TRACE_CHECKPOINT(); + * + * ... + * + * TRACE_CHECKPOINT(); + * } + * + * profiler_dump(1000); + * + * + * Output: + * + * Name Total Time Breakdown + * ------------------------------------------------- + my_func 15.33 + 0: 4.23 + 1: 11.10 + + */ + +typedef struct { + uint32_t total_time; + uint32_t calls; +} Checkpoint; + +typedef struct { + char name[128]; + uint32_t calls; + uint32_t start; + uint32_t total_time; + Checkpoint checkpoints[16]; + uint8_t max_checkpoints; +} Trace; + +struct Profiler { + Trace traces[256]; + uint8_t trace_count; +}; + +extern Profiler __profiler; + +void profiler_init(); +void profiler_dump(uint32_t ms); +void profiler_register_trace(Trace* trace, const char* func_name); +void profiler_trace_start(Trace* trace); +void profiler_trace_checkpoint(Trace* trace, int counter); + +#define TRACE_START() \ + int __sc = 0; \ + static char __trace_registered = 0; + static Trace __trace; \ + if(!_trace_registered) {profiler_register_trace(&__trace, __func__); __trace_registered = 1;} \ + profiler_trace_start(&__trace); + +#define TRACE_CHECKPOINT() \ + profiler_trace_checkpoint(&__trace, __sc++); + + +#endif // PROFILE_H