|
| 1 | +#include "profiler.hpp" |
| 2 | + |
| 3 | +void Profiler::begin(const char* name) { |
| 4 | +#ifdef PROFILE |
| 5 | + // search for a section by name or an empty slot |
| 6 | + for (uint32_t i = 0; i < PROF_MAX_SECTIONS; i++) { |
| 7 | + if (strncmp(sections[i].name, name, PROF_MAX_NAME) == 0 || (sections[i].count == 0 && sections[i].overflow == 0)) { |
| 8 | + // start this section |
| 9 | + strncpy(sections[i].name, name, PROF_MAX_NAME); |
| 10 | + sections[i].name[PROF_MAX_NAME] = '\0'; // ensure null termination |
| 11 | + if (sections[i].count < PROF_MAX_TIMES) { |
| 12 | + sections[i].start_times[sections[i].count] = micros(); |
| 13 | + sections[i].started = 1; // set this section as "started" |
| 14 | + } |
| 15 | + return; |
| 16 | + } |
| 17 | + } |
| 18 | +#endif |
| 19 | +} |
| 20 | + |
| 21 | +void Profiler::end(const char* name) { |
| 22 | +#ifdef PROFILE |
| 23 | + // find the section by name and add an end time |
| 24 | + for (uint32_t i = 0; i < PROF_MAX_SECTIONS; i++) { |
| 25 | + if (strncmp(sections[i].name, name, PROF_MAX_NAME) == 0) { |
| 26 | + uint32_t count = sections[i].count; |
| 27 | + if (count < PROF_MAX_TIMES) { |
| 28 | + sections[i].end_times[count] = micros(); |
| 29 | + sections[i].count++; |
| 30 | + sections[i].started = 0; // set this section as "finished" |
| 31 | + // if this value just overflowed, or it has reached the max time count, |
| 32 | + // mark it as overflowed and reset to 0 |
| 33 | + if (sections[i].count == 0 || sections[i].count == PROF_MAX_TIMES) { |
| 34 | + sections[i].overflow = 1; |
| 35 | + sections[i].count = 0; |
| 36 | + } |
| 37 | + } |
| 38 | + return; |
| 39 | + } |
| 40 | + } |
| 41 | +#endif |
| 42 | +} |
| 43 | + |
| 44 | +void Profiler::print(const char* name) { |
| 45 | +#ifdef PROFILE |
| 46 | + uint32_t min = UINT32_MAX; |
| 47 | + uint32_t max = 0; |
| 48 | + uint32_t sum = 0; |
| 49 | + |
| 50 | + for (uint32_t i = 0; i < PROF_MAX_SECTIONS; i++) { |
| 51 | + if (strncmp(sections[i].name, name, PROF_MAX_NAME) != 0) continue; |
| 52 | + // find actual count since this value can overflow/max out |
| 53 | + uint32_t actual_count = sections[i].overflow ? PROF_MAX_TIMES : sections[i].count; |
| 54 | + for (unsigned int j = 0; j < actual_count; j++) { |
| 55 | + // if end() was not called when we decide to print, ignore the "bad" section reading |
| 56 | + if (sections[i].started && j == sections[i].count) continue; |
| 57 | + |
| 58 | + uint32_t delta = sections[i].end_times[j] - sections[i].start_times[j]; |
| 59 | + // sum all deltas to be averaged upon printing |
| 60 | + sum += delta; |
| 61 | + if (delta < min) min = delta; |
| 62 | + if (delta > max) max = delta; |
| 63 | + } |
| 64 | + // print stats |
| 65 | + Serial.printf("Profiling for: %s\n Min: %u us\n Max: %u us\n Avg: %u us\n", |
| 66 | + name, min, max, sum / actual_count); |
| 67 | + return; |
| 68 | + } |
| 69 | +#endif |
| 70 | +} |
0 commit comments