diff options
Diffstat (limited to 'src/profiling.c')
-rw-r--r-- | src/profiling.c | 253 |
1 files changed, 90 insertions, 163 deletions
diff --git a/src/profiling.c b/src/profiling.c index 0255552..6b073ed 100644 --- a/src/profiling.c +++ b/src/profiling.c | |||
@@ -6,184 +6,111 @@ | |||
6 | #define PROF_ENABLE 0 | 6 | #define PROF_ENABLE 0 |
7 | #endif | 7 | #endif |
8 | 8 | ||
9 | #if PROF_ENABLE > 0 && PROF_ENABLE < 3 | 9 | #if PROF_ENABLE > 0 |
10 | 10 | ||
11 | #ifndef PROF_N_FRAMES | 11 | #ifndef PROF_RESET_MINMAX |
12 | #define PROF_N_FRAMES 30 | 12 | #define PROF_RESET_MINMAX false |
13 | #endif | 13 | #endif |
14 | 14 | ||
15 | // Profile method 1: Average per N frames. | 15 | // Maximum number of profiling to monitor. |
16 | #if PROF_ENABLE == 1 | 16 | typedef enum ProfType { |
17 | #define TEXT_ENABLE 1 | 17 | PROF_INPUT, |
18 | #define PROF(F,VAR) \ | 18 | PROF_UPDATE, |
19 | do { \ | 19 | PROF_RENDER, |
20 | u32 __tmp_prof = profile_measure();\ | 20 | PROF_FLIP, |
21 | F;\ | 21 | PROF_FILL, |
22 | (VAR) += profile_measure() - __tmp_prof;\ | 22 | PROF_NUM, |
23 | } while (0) | 23 | } ProfType; |
24 | 24 | ||
25 | // Profile method 2: Maximum in N frames. | 25 | char *prof_type_str[PROF_NUM] = { |
26 | #elif PROF_ENABLE == 2 | 26 | "INPUT ", |
27 | #define TEXT_ENABLE 1 | 27 | "UPDATE ", |
28 | #define PROF(F,VAR) \ | 28 | "RENDER ", |
29 | do { \ | 29 | "FLIPBUF", |
30 | u32 __tmp_prof = profile_measure();\ | 30 | "SCRFILL", |
31 | (F);\ | 31 | }; |
32 | (VAR) = MAX(profile_measure() - __tmp_prof, (VAR));\ | ||
33 | } while (0) | ||
34 | #endif | ||
35 | 32 | ||
36 | #ifndef PROF_SHOW_X | 33 | u32 prof_frame_time = 0; |
37 | #define PROF_SHOW_X 0 | 34 | u32 prof_frame_count = 0; |
38 | #endif | 35 | u32 prof_frame_avg = -1; |
39 | #ifndef PROF_SHOW_Y | 36 | u32 prof_frame_time_max = 0; |
40 | #define PROF_SHOW_Y 0 | 37 | u32 prof_times[PROF_NUM] = {0}; |
41 | #endif | 38 | u32 prof_count[PROF_NUM] = {0}; |
39 | u32 prof_avg[PROF_NUM] = {0}; | ||
40 | u32 prof_max[PROF_NUM] = {0}; | ||
41 | u32 prof_min[PROF_NUM] = {0}; | ||
42 | 42 | ||
43 | static bool profile_show = true; | 43 | bool prof_reset_minmax = PROF_RESET_MINMAX; |
44 | bool prof_show = true; | ||
44 | 45 | ||
45 | #define PROF_SHOW() \ | 46 | #define PROF_INIT() do { \ |
46 | do { \ | 47 | for (size_t i = 0; i < PROF_NUM; i++) { \ |
47 | if (key_tap(KEY_START)) {\ | 48 | prof_min[i] = -1; \ |
48 | profile_show ^= 1;\ | 49 | } \ |
49 | }\ | 50 | } while(0); |
50 | if (profile_show) {\ | ||
51 | txt_color(1);\ | ||
52 | txt_position((PROF_SHOW_X), (PROF_SHOW_Y));\ | ||
53 | draw_filled_rect((PROF_SHOW_X), (PROF_SHOW_X), 8 * 14, 8 * 10, 0);\ | ||
54 | txt_printf("VIDEO\n");\ | ||
55 | txt_printf(">CLEAR %.8lu\n", avg_clear_cycles);\ | ||
56 | txt_printf(">FLIP %.8lu\n", avg_flip_cycles);\ | ||
57 | txt_printf("SEQUENCER RENDER\n");\ | ||
58 | txt_printf(">TRIGS %.8lu\n", avg_draw_trigs_cycles);\ | ||
59 | txt_printf(">BTNS %.8lu\n", avg_draw_btns_cycles);\ | ||
60 | txt_printf(">PARAM %.8lu\n", avg_draw_param_cycles);\ | ||
61 | txt_printf(">PIANO %.8lu\n", avg_draw_piano_cycles);\ | ||
62 | txt_printf(">CURSOR %.8lu\n", avg_draw_cursor_cycles);\ | ||
63 | txt_printf("UPDATE %.8lu\n", avg_update_cycles);\ | ||
64 | txt_printf("INPUT %.8lu\n", avg_input_cycles);\ | ||
65 | txt_printf("RENDER %.8lu\n", avg_render_cycles);\ | ||
66 | txt_printf("TOTAL %.8lu\n", avg_frame_cycles);\ | ||
67 | txt_render();\ | ||
68 | }\ | ||
69 | u32 frame_time =\ | ||
70 | FP_DIV(\ | ||
71 | FP_NUM(avg_frame_cycles + 1, 2),\ | ||
72 | FP_NUM(2809, 2),\ | ||
73 | 2) * 166;\ | ||
74 | u32 fps =\ | ||
75 | FP_DIV(\ | ||
76 | FP_NUM(280896 * 60, 2),\ | ||
77 | FP_NUM(avg_frame_cycles + 1, 2),\ | ||
78 | 2);\ | ||
79 | draw_filled_rect(8 * 18, 0, 239, 16, 0);\ | ||
80 | txt_drawf("TIME: %.6lu", 8 * 18, 0, 1, frame_time >> 2);\ | ||
81 | txt_drawf("MAX FPS: %.4lu", 8 * 18, 8, 1, (fps >> 2) + 1);\ | ||
82 | } while (0) | ||
83 | 51 | ||
84 | static u32 prof_frame_counter = 0; | 52 | #define PROF(func, idx) do { \ |
53 | u32 time_before = profile_measure(); \ | ||
54 | (func); \ | ||
55 | u32 time_after = profile_measure(); \ | ||
56 | u32 time_current = time_after - time_before; \ | ||
57 | prof_times[idx] += time_current; \ | ||
58 | prof_count[idx]++; \ | ||
59 | prof_max[idx] = MAX(time_current, prof_max[idx]);\ | ||
60 | prof_min[idx] = MIN(time_current, prof_min[idx]);\ | ||
61 | } while(0); | ||
85 | 62 | ||
86 | static u32 frame_cycles = 0; | 63 | #define FRAME_START() do { \ |
87 | static u32 flip_cycles = 0; | 64 | profile_start();\ |
88 | static u32 clear_cycles = 0; | 65 | } while(0) |
89 | static u32 input_cycles = 0; | ||
90 | static u32 draw_trigs_cycles = 0; | ||
91 | static u32 draw_btn_cycles = 0; | ||
92 | static u32 draw_piano_cycles = 0; | ||
93 | static u32 draw_param_cycles = 0; | ||
94 | static u32 draw_cursor_cycles = 0; | ||
95 | static u32 render_cycles = 0; | ||
96 | static u32 update_cycles = 0; | ||
97 | 66 | ||
98 | static u32 avg_frame_cycles = 0; | 67 | #define FRAME_END() do { \ |
99 | static u32 avg_flip_cycles = 0; | 68 | prof_frame_count++;\ |
100 | static u32 avg_clear_cycles = 0; | 69 | prof_frame_time_max = MAX(prof_frame_time_max, profile_measure());\ |
101 | static u32 avg_input_cycles = 0; | 70 | prof_frame_time += profile_stop();\ |
102 | static u32 avg_draw_trigs_cycles = 0; | 71 | if (prof_show) { \ |
103 | static u32 avg_draw_btns_cycles = 0; | 72 | draw_filled_rect(0, 0, SCREEN_WIDTH - 1, 8 * (PROF_NUM + 1), 0); \ |
104 | static u32 avg_draw_piano_cycles = 0; | 73 | txt_drawf_small("FRAME TIME/FPS: %.9l/%.2l", 0, 0, COL_FG, \ |
105 | static u32 avg_draw_param_cycles = 0; | 74 | prof_frame_avg, \ |
106 | static u32 avg_draw_cursor_cycles = 0; | 75 | (u32)((u64)280896 * 60 / (prof_frame_avg + 1)));\ |
107 | static u32 avg_render_cycles = 0; | 76 | txt_drawf_small("MAX: %.9l/%l", 8 * 19, 0, COL_FG, \ |
108 | static u32 avg_update_cycles = 0; | 77 | prof_frame_time_max,280896);\ |
78 | for (size_t idx = 0; idx < PROF_NUM; idx++) { \ | ||
79 | txt_drawf_small("%s %.9l (%.9l %.9l) %08x:%08x", 0, 8 * (idx + 1), COL_FG, \ | ||
80 | prof_type_str[idx], \ | ||
81 | prof_avg[idx], \ | ||
82 | prof_min[idx], \ | ||
83 | prof_max[idx], \ | ||
84 | prof_avg[idx], \ | ||
85 | prof_max[idx]);\ | ||
86 | }; \ | ||
87 | } \ | ||
88 | if (prof_frame_count >= PROF_ENABLE) { \ | ||
89 | for (size_t idx = 0; idx < PROF_NUM; idx++) { \ | ||
90 | prof_avg[idx] = prof_times[idx] / prof_frame_count; \ | ||
91 | if (prof_reset_minmax) { \ | ||
92 | prof_min[idx] = -1; \ | ||
93 | prof_max[idx] = 0; \ | ||
94 | } \ | ||
95 | prof_times[idx] = 0; \ | ||
96 | prof_count[idx] = 0; \ | ||
97 | }; \ | ||
98 | prof_frame_avg = prof_frame_time / prof_frame_count; \ | ||
99 | prof_frame_count = 0; \ | ||
100 | prof_frame_time = 0; \ | ||
101 | } \ | ||
102 | } while(0) | ||
109 | 103 | ||
110 | #if PROF_ENABLE == 1 | 104 | #define PROF_SHOW() do { \ |
111 | #define FRAME_START()\ | 105 | prof_show ^= 1; \ |
112 | do { \ | 106 | } while(0) |
113 | if (prof_frame_counter == PROF_N_FRAMES) {\ | ||
114 | avg_frame_cycles = frame_cycles / prof_frame_counter;\ | ||
115 | avg_flip_cycles = flip_cycles / prof_frame_counter;\ | ||
116 | avg_clear_cycles = clear_cycles / prof_frame_counter;\ | ||
117 | avg_draw_trigs_cycles = draw_trigs_cycles / prof_frame_counter;\ | ||
118 | avg_draw_btns_cycles = draw_btn_cycles / prof_frame_counter;\ | ||
119 | avg_draw_piano_cycles = draw_piano_cycles / prof_frame_counter;\ | ||
120 | avg_draw_param_cycles = draw_param_cycles / prof_frame_counter;\ | ||
121 | avg_draw_cursor_cycles = draw_cursor_cycles / prof_frame_counter;\ | ||
122 | avg_input_cycles = input_cycles / prof_frame_counter;\ | ||
123 | avg_render_cycles = render_cycles / prof_frame_counter;\ | ||
124 | avg_update_cycles = update_cycles / prof_frame_counter;\ | ||
125 | frame_cycles = 0;\ | ||
126 | flip_cycles = 0;\ | ||
127 | clear_cycles = 0;\ | ||
128 | input_cycles = 0;\ | ||
129 | render_cycles = 0;\ | ||
130 | update_cycles = 0;\ | ||
131 | draw_trigs_cycles = 0;\ | ||
132 | draw_param_cycles = 0;\ | ||
133 | draw_cursor_cycles = 0;\ | ||
134 | draw_btn_cycles = 0;\ | ||
135 | draw_piano_cycles = 0;\ | ||
136 | prof_frame_counter = 0;\ | ||
137 | }\ | ||
138 | profile_start();\ | ||
139 | } while (0) | ||
140 | #elif PROF_ENABLE == 2 | ||
141 | #define FRAME_START()\ | ||
142 | do { \ | ||
143 | if (prof_frame_counter == PROF_N_FRAMES) {\ | ||
144 | avg_frame_cycles = frame_cycles;\ | ||
145 | avg_flip_cycles = flip_cycles;\ | ||
146 | avg_clear_cycles = clear_cycles;\ | ||
147 | avg_line_cycles = line_cycles;\ | ||
148 | avg_rect_cycles = rect_cycles;\ | ||
149 | avg_fill_rect_cycles = fill_rect_cycles;\ | ||
150 | avg_chr_cycles = chr_cycles;\ | ||
151 | avg_icn_cycles = icn_cycles;\ | ||
152 | avg_txt_drawf_cycles = txt_drawf_cycles;\ | ||
153 | avg_txt_printf_cycles = txt_printf_cycles;\ | ||
154 | avg_txt_render_cycles = txt_render_cycles;\ | ||
155 | avg_txt_clear_cycles = txt_clear_cycles;\ | ||
156 | avg_input_cycles = input_cycles;\ | ||
157 | frame_cycles = 0;\ | ||
158 | flip_cycles = 0;\ | ||
159 | clear_cycles = 0;\ | ||
160 | line_cycles = 0;\ | ||
161 | rect_cycles = 0;\ | ||
162 | fill_rect_cycles = 0;\ | ||
163 | chr_cycles = 0;\ | ||
164 | icn_cycles = 0;\ | ||
165 | txt_drawf_cycles = 0;\ | ||
166 | txt_printf_cycles = 0;\ | ||
167 | txt_render_cycles = 0;\ | ||
168 | txt_clear_cycles = 0;\ | ||
169 | input_cycles = 0;\ | ||
170 | prof_frame_counter = 0;\ | ||
171 | }\ | ||
172 | profile_start();\ | ||
173 | } while (0) | ||
174 | #endif | ||
175 | |||
176 | #define FRAME_END() \ | ||
177 | do { \ | ||
178 | prof_frame_counter++;\ | ||
179 | frame_cycles += profile_stop();\ | ||
180 | } while (0) | ||
181 | 107 | ||
182 | #else | 108 | #else |
183 | 109 | ||
184 | // No profiling. | 110 | // No profiling. |
185 | #define PROF(F,VAR) (F) | 111 | #define PROF_INIT() |
186 | #define PROF_SHOW() | 112 | #define PROF(F,VAR) do {F;} while(0) |
187 | #define FRAME_START() | 113 | #define FRAME_START() |
188 | #define FRAME_END() | 114 | #define FRAME_END() |
115 | #define PROF_SHOW() | ||
189 | #endif | 116 | #endif |