diff options
| author | Ginger Bill <bill@gingerbill.org> | 2016-10-09 20:14:32 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2016-10-09 20:14:32 +0100 |
| commit | 90babbfbf30cc9c611af74e8c0af3562faf4d58b (patch) | |
| tree | 72fa8156a0dfececd67a3ad0943fa16661385503 /src/profiler.cpp | |
| parent | 5bffa4ee793a891237538cb4d18754bed4d43748 (diff) | |
Very Basic Profiling
Diffstat (limited to 'src/profiler.cpp')
| -rw-r--r-- | src/profiler.cpp | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/profiler.cpp b/src/profiler.cpp new file mode 100644 index 000000000..388e99b4f --- /dev/null +++ b/src/profiler.cpp @@ -0,0 +1,120 @@ +// #define PROF_TIMINGS + +struct ProfInfo { + String name; + HashKey hash; + i32 count; + i64 total_time; +}; + +struct Profiler { + Map<ProfInfo> info; // Key: String + isize max_name_len; + i64 start_time; +}; + +gb_global Profiler global_profiler; + +i64 prof_get_timestamp(void) { + LARGE_INTEGER counter; + QueryPerformanceCounter(&counter); + return counter.QuadPart; +} + +void prof_init(void) { +#if defined(PROF_TIMINGS) + map_init(&global_profiler.info, gb_heap_allocator()); + global_profiler.start_time = prof_get_timestamp(); +#endif +} + + + + +ProfInfo prof_begin(String name) { + ProfInfo info = {}; + info.name = name; + info.hash = hash_pointer(name.text); // NOTE(bill): Requires it to be unique + + info.total_time = prof_get_timestamp(); + return info; +} + +void prof_end(ProfInfo info) { + i64 dt = prof_get_timestamp() - info.total_time; + info.total_time = dt; + + auto *found = map_get(&global_profiler.info, info.hash); + if (found) { + found->count++; + found->total_time += info.total_time; + } else { + info.count++; + map_set(&global_profiler.info, info.hash, info); + if (global_profiler.max_name_len < info.name.len) { + global_profiler.max_name_len = info.name.len; + } + } +} + +struct ScopedProfInfo { + ProfInfo info; + ScopedProfInfo(String name) { + info = prof_begin(name); + } + ~ScopedProfInfo() { + prof_end(info); + } +}; + +#if defined(PROF_TIMINGS) +#define PROF_SCOPED(msg) ScopedProfInfo scoped_prof_info_##__COUNTER__ = ScopedProfInfo(make_string(cast(u8 *)msg, gb_size_of(msg)-1)) +#else +#define PROF_SCOPED(msg) do {} while (0) +#endif +#define PROF_PROC() PROF_SCOPED(__FUNCTION__) + +void prof_print_all(void) { +#if defined(PROF_TIMINGS) + LARGE_INTEGER win32_perf_count_freq = {0}; + QueryPerformanceFrequency(&win32_perf_count_freq); + GB_ASSERT(win32_perf_count_freq.QuadPart != 0); + + gb_printf("Profiler Timings\n"); + + i32 string_offset = cast(int)global_profiler.max_name_len; + char spaces[] = " "; + char dashses[] = "--------------------------------------------------------------------------------"; + isize pad_len = gb_size_of(spaces)-1; + + isize info_count = global_profiler.info.entries.count; + ProfInfo *info_data = gb_alloc_array(gb_heap_allocator(), ProfInfo, info_count); + defer (gb_free(gb_heap_allocator(), info_data)); + for (isize i = 0; i < info_count; i++) { + info_data[i] = global_profiler.info.entries[i].value; + } + + gb_sort_array(info_data, info_count, gb_i64_cmp(gb_offset_of(ProfInfo, total_time))); + + for (isize i = info_count-1; i >= 0; i--) { + auto entry = info_data + i; + f64 dt = (1000.0*entry->total_time / cast(f64)win32_perf_count_freq.QuadPart); + int pad = global_profiler.max_name_len - entry->name.len; + pad = gb_max(pad, 0); + gb_printf("%.*s%*.*s - %.3f ms - %.3f us\n", + LIT(entry->name), + pad, pad, spaces, + dt, 1000.0*dt/cast(f64)entry->count); + } + + i64 total_time = prof_get_timestamp() - global_profiler.start_time; + f64 total_time_ms = (1000.0*total_time / cast(f64)win32_perf_count_freq.QuadPart); + + + gb_printf("%*.*s\n" + "%*.*s %.3f ms\n", + global_profiler.max_name_len, global_profiler.max_name_len, dashses, + global_profiler.max_name_len, global_profiler.max_name_len, spaces, + total_time_ms); +#endif +} |