#include "profiler.h" #include #include #include #include typedef struct { uint32_t start; uint32_t length; uint32_t count; } ProfilerRecord; DICT_DEF2(ProfilerRecordDict, const char*, M_CSTR_OPLIST, ProfilerRecord, M_POD_OPLIST) #define M_OPL_ProfilerRecord_t() DICT_OPLIST(ProfilerRecord, M_CSTR_OPLIST, M_POD_OPLIST) struct Profiler { ProfilerRecordDict_t records; }; Profiler* profiler_alloc() { Profiler* profiler = malloc(sizeof(Profiler)); ProfilerRecordDict_init(profiler->records); return profiler; } void profiler_free(Profiler* profiler) { ProfilerRecordDict_clear(profiler->records); free(profiler); } void profiler_prealloc(Profiler* profiler, const char* key) { ProfilerRecord record = { .start = 0, .length = 0, .count = 0, }; ProfilerRecordDict_set_at(profiler->records, key, record); } void profiler_start(Profiler* profiler, const char* key) { ProfilerRecord* record = ProfilerRecordDict_get(profiler->records, key); if(record == NULL) { profiler_prealloc(profiler, key); record = ProfilerRecordDict_get(profiler->records, key); } furi_check(record->start == 0); record->start = DWT->CYCCNT; } void profiler_stop(Profiler* profiler, const char* key) { ProfilerRecord* record = ProfilerRecordDict_get(profiler->records, key); furi_check(record != NULL); record->length += DWT->CYCCNT - record->start; record->start = 0; record->count++; } void profiler_dump(Profiler* profiler) { printf("Profiler:\r\n"); ProfilerRecordDict_it_t it; for(ProfilerRecordDict_it(it, profiler->records); !ProfilerRecordDict_end_p(it); ProfilerRecordDict_next(it)) { const ProfilerRecordDict_itref_t* itref = ProfilerRecordDict_cref(it); uint32_t count = itref->value.count; uint32_t clocks = itref->value.length; double us = (double)clocks / (double)64.0; double ms = (double)clocks / (double)64000.0; double s = (double)clocks / (double)64000000.0; printf("\t%s[%lu]: %f s, %f ms, %f us, %lu clk\r\n", itref->key, count, s, ms, us, clocks); if(count > 1) { us /= (double)count; ms /= (double)count; s /= (double)count; clocks /= count; printf("\t%s[1]: %f s, %f ms, %f us, %lu clk\r\n", itref->key, s, ms, us, clocks); } } }