profiler.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #include "profiler.h"
  2. static struct {
  3. int cursor;
  4. struct {
  5. const char *msg;
  6. ATimeUs delta;
  7. } event[65536];
  8. int frame;
  9. ATimeUs last_print_time;
  10. ATimeUs profiler_time;
  11. ATimeUs frame_deltas, last_frame;
  12. int counted_frame;
  13. } profiler;
  14. void profilerInit() {
  15. profiler.cursor = 0;
  16. profiler.frame = 0;
  17. profiler.last_print_time = 0;
  18. profiler.profiler_time = 0;
  19. profiler.frame_deltas = profiler.last_frame = 0;
  20. profiler.counted_frame = 0;
  21. }
  22. void profileEvent(const char *msg, ATimeUs delta) {
  23. ATTO_ASSERT(profiler.cursor < 65536);
  24. profiler.event[profiler.cursor].msg = msg;
  25. profiler.event[profiler.cursor].delta = delta;
  26. ++profiler.cursor;
  27. }
  28. typedef struct {
  29. const char *name;
  30. int count;
  31. ATimeUs total_time;
  32. ATimeUs min_time;
  33. ATimeUs max_time;
  34. } ProfilerLocation;
  35. int profilerFrame(struct Stack *stack_temp) {
  36. int retval = 0;
  37. const ATimeUs start = aAppTime();
  38. profiler.frame_deltas += start - profiler.last_frame;
  39. void *tmp_cursor = stackGetCursor(stack_temp);
  40. const int max_array_size = stackGetFree(stack_temp) / sizeof(ProfilerLocation);
  41. int array_size = 0;
  42. ProfilerLocation *array = tmp_cursor;
  43. int total_time = 0;
  44. for (int i = 0; i < profiler.cursor; ++i) {
  45. ProfilerLocation *loc = 0;
  46. for (int j = 0; j < array_size; ++j)
  47. if (array[j].name == profiler.event[i].msg) {
  48. loc = array + j;
  49. break;
  50. }
  51. if (!loc) {
  52. ATTO_ASSERT(array_size< max_array_size);
  53. loc = array + array_size++;
  54. loc->name = profiler.event[i].msg;
  55. loc->count = 0;
  56. loc->total_time = 0;
  57. loc->min_time = 0x7fffffffu;
  58. loc->max_time = 0;
  59. }
  60. ++loc->count;
  61. const ATimeUs delta = profiler.event[i].delta;
  62. loc->total_time += delta;
  63. total_time += delta;
  64. if (delta < loc->min_time) loc->min_time = delta;
  65. if (delta > loc->max_time) loc->max_time = delta;
  66. }
  67. ++profiler.counted_frame;
  68. ++profiler.frame;
  69. if (start - profiler.last_print_time > 1000000) {
  70. PRINT("=================================================");
  71. const ATimeUs dt = profiler.frame_deltas / profiler.counted_frame;
  72. PRINTF("avg frame = %dus (fps = %f)", dt, 1000000. / dt);
  73. PRINTF("PROF: frame=%d, total_frame_time=%d total_prof_time=%d, avg_prof_time=%d events=%d unique=%d",
  74. profiler.frame, total_time, profiler.profiler_time, profiler.profiler_time / profiler.frame,
  75. profiler.cursor, array_size);
  76. for (int i = 0; i < array_size; ++i) {
  77. const ProfilerLocation *loc = array + i;
  78. PRINTF("T%d: total=%d count=%d min=%d max=%d, avg=%d %s",
  79. i, loc->total_time, loc->count, loc->min_time, loc->max_time,
  80. loc->total_time / loc->count, loc->name);
  81. }
  82. #if 0
  83. #define TOP_N 10
  84. int max_time[TOP_N] = {0};
  85. int max_count[TOP_N] = {0};
  86. for (int i = 0; i < array_size; ++i) {
  87. const ProfilerLocation *loc = array + i;
  88. for (int j = 0; j < TOP_N; ++j)
  89. if (array[max_time[j]].max_time < loc->max_time) {
  90. for (int k = j + 1; k < TOP_N; ++k) max_time[k] = max_time[k - 1];
  91. max_time[j] = i;
  92. break;
  93. }
  94. for (int j = 0; j < TOP_N; ++j)
  95. if (array[max_count[j]].count < loc->count) {
  96. for (int k = j + 1; k < TOP_N; ++k) max_count[k] = max_count[k - 1];
  97. max_count[j] = i;
  98. break;
  99. }
  100. }
  101. if (array_size > TOP_N) {
  102. for (int i = 0; i < TOP_N; ++i) {
  103. const ProfilerLocation *loc = array + max_time[i];
  104. PRINTF("T%d %d: total=%d count=%d min=%d max=%d, avg=%d %s",
  105. i, max_time[i], loc->total_time, loc->count, loc->min_time, loc->max_time,
  106. loc->total_time / loc->count, loc->name);
  107. }
  108. for (int i = 0; i < TOP_N; ++i) {
  109. const ProfilerLocation *loc = array + max_count[i];
  110. PRINTF("C%d %d: total=%d count=%d min=%d max=%d, avg=%d %s",
  111. i, max_count[i], loc->total_time, loc->count, loc->min_time, loc->max_time,
  112. loc->total_time / loc->count, loc->name);
  113. }
  114. }
  115. #endif
  116. profiler.last_print_time = start;
  117. profiler.counted_frame = 0;
  118. profiler.frame_deltas = 0;
  119. retval = 1;
  120. }
  121. profiler.last_frame = start;
  122. profiler.profiler_time += aAppTime() - start;
  123. profiler.cursor = 0;
  124. profileEvent("PROFILER", aAppTime() - start);
  125. return retval;
  126. }