profiler.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #include "profiler.h"
  2. #include <stdlib.h>
  3. #include <m-dict.h>
  4. #include <furi.h>
  5. #include <furi_hal_gpio.h>
  6. typedef struct {
  7. uint32_t start;
  8. uint32_t length;
  9. uint32_t count;
  10. } ProfilerRecord;
  11. DICT_DEF2(ProfilerRecordDict, const char*, M_CSTR_OPLIST, ProfilerRecord, M_POD_OPLIST)
  12. #define M_OPL_ProfilerRecord_t() DICT_OPLIST(ProfilerRecord, M_CSTR_OPLIST, M_POD_OPLIST)
  13. struct Profiler {
  14. ProfilerRecordDict_t records;
  15. };
  16. Profiler* profiler_alloc() {
  17. Profiler* profiler = malloc(sizeof(Profiler));
  18. ProfilerRecordDict_init(profiler->records);
  19. return profiler;
  20. }
  21. void profiler_free(Profiler* profiler) {
  22. ProfilerRecordDict_clear(profiler->records);
  23. free(profiler);
  24. }
  25. void profiler_prealloc(Profiler* profiler, const char* key) {
  26. ProfilerRecord record = {
  27. .start = 0,
  28. .length = 0,
  29. .count = 0,
  30. };
  31. ProfilerRecordDict_set_at(profiler->records, key, record);
  32. }
  33. void profiler_start(Profiler* profiler, const char* key) {
  34. ProfilerRecord* record = ProfilerRecordDict_get(profiler->records, key);
  35. if(record == NULL) {
  36. profiler_prealloc(profiler, key);
  37. record = ProfilerRecordDict_get(profiler->records, key);
  38. }
  39. furi_check(record->start == 0);
  40. record->start = DWT->CYCCNT;
  41. }
  42. void profiler_stop(Profiler* profiler, const char* key) {
  43. ProfilerRecord* record = ProfilerRecordDict_get(profiler->records, key);
  44. furi_check(record != NULL);
  45. record->length += DWT->CYCCNT - record->start;
  46. record->start = 0;
  47. record->count++;
  48. }
  49. void profiler_dump(Profiler* profiler) {
  50. printf("Profiler:\r\n");
  51. ProfilerRecordDict_it_t it;
  52. for(ProfilerRecordDict_it(it, profiler->records); !ProfilerRecordDict_end_p(it);
  53. ProfilerRecordDict_next(it)) {
  54. const ProfilerRecordDict_itref_t* itref = ProfilerRecordDict_cref(it);
  55. uint32_t count = itref->value.count;
  56. uint32_t clocks = itref->value.length;
  57. double us = (double)clocks / (double)64.0;
  58. double ms = (double)clocks / (double)64000.0;
  59. double s = (double)clocks / (double)64000000.0;
  60. printf("\t%s[%lu]: %f s, %f ms, %f us, %lu clk\r\n", itref->key, count, s, ms, us, clocks);
  61. if(count > 1) {
  62. us /= (double)count;
  63. ms /= (double)count;
  64. s /= (double)count;
  65. clocks /= count;
  66. printf("\t%s[1]: %f s, %f ms, %f us, %lu clk\r\n", itref->key, s, ms, us, clocks);
  67. }
  68. }
  69. }