From 74eb2bf14f7e82c86419374bfd46b6cfd89f2df8 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Thu, 20 Apr 2023 14:51:09 +0200 Subject: Add improved avg profiling method --- src/main.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 104 insertions(+), 25 deletions(-) diff --git a/src/main.c b/src/main.c index b6a979f..b1562ca 100644 --- a/src/main.c +++ b/src/main.c @@ -39,49 +39,59 @@ #define PROF_ENABLE 2 -#ifdef PROF_ENABLE -#if PROF_ENABLE == 0 -#define TEXT_ENABLE 1 -#define PROF(F,VAR) (profile_start(),(F),(VAR) = profile_stop()) -#elif PROF_ENABLE == 1 +#if PROF_ENABLE > 0 && PROF_ENABLE < 3 + +#ifndef PROF_N_FRAMES +#define PROF_N_FRAMES 15 +#endif + +#if PROF_ENABLE == 1 +// Profile method 1: Average per N frames. #define TEXT_ENABLE 1 -#define PROF(F,VAR) (profile_start(),(F),(VAR) = MAX(profile_stop(), (VAR))) -#elif PROF_ENABLE == 2 #define PROF(F,VAR) \ do { \ u32 __tmp_prof = profile_measure();\ (F);\ - (VAR) = profile_measure() - __tmp_prof;\ + (VAR) += profile_measure() - __tmp_prof;\ } while (0) + +#elif PROF_ENABLE == 2 +// Profile method 2: Maximum in N frames. #define TEXT_ENABLE 1 -// TODO: allow measuring inside a PROF function using profile_measure to store -// temporary values and calcualting the difference. -// TODO: allow per frame or per 60 second averaging of cycle measurement. -// TODO: calculate fps based on frame timing. +#define PROF(F,VAR) \ + do { \ + u32 __tmp_prof = profile_measure();\ + (F);\ + (VAR) = MAX(profile_measure() - __tmp_prof, (VAR));\ + } while (0) #endif + #ifndef PROF_SHOW_X #define PROF_SHOW_X 0 #endif #ifndef PROF_SHOW_Y #define PROF_SHOW_Y 0 #endif + #define PROF_SHOW() \ do { \ txt_position((PROF_SHOW_X), (PROF_SHOW_Y));\ - txt_printf("INPUT %.8lu\n", input_cycles);\ - txt_printf("EVAL %.8lu\n", eval_cycles);\ + txt_printf("INPUT %.8lu\n", avg_input_cycles);\ + txt_printf("EVAL %.8lu\n", avg_eval_cycles);\ txt_printf("VIDEO\n");\ - txt_printf(">PIX %.8lu\n", ppu_pixel_cycles);\ - txt_printf(">FILL %.8lu\n", ppu_fill_cycles);\ - txt_printf(">1BPP %.8lu\n", ppu_icn_cycles);\ - txt_printf(">2BPP %.8lu\n", ppu_chr_cycles);\ - txt_printf(">FLIP %.8lu\n", flip_cycles);\ - txt_printf("AUDIO %.8lu\n", mix_cycles);\ - txt_printf("FRAME %.8lu\n", frame_cycles);\ + txt_printf(">PIX %.8lu\n", avg_ppu_pixel_cycles);\ + txt_printf(">FILL %.8lu\n", avg_ppu_fill_cycles);\ + txt_printf(">1BPP %.8lu\n", avg_ppu_icn_cycles);\ + txt_printf(">2BPP %.8lu\n", avg_ppu_chr_cycles);\ + txt_printf(">FLIP %.8lu\n", avg_flip_cycles);\ + txt_printf("AUDIO %.8lu\n", avg_mix_cycles);\ + txt_printf("TOTAL %.8lu\n", avg_frame_cycles);\ screen_fill(BG_BACK, 0, 0, 8 * 16, 8 * 10, 0);\ flipbuf();\ } while (0) +static u32 prof_frame_counter = 0; + static u32 frame_cycles = 0; static u32 ppu_pixel_cycles = 0; static u32 ppu_fill_cycles = 0; @@ -91,15 +101,84 @@ static u32 flip_cycles = 0; static u32 eval_cycles = 0; static u32 input_cycles = 0; static u32 mix_cycles = 0; + +static u32 avg_ppu_pixel_cycles = 0; +static u32 avg_ppu_fill_cycles = 0; +static u32 avg_ppu_chr_cycles = 0; +static u32 avg_ppu_icn_cycles = 0; +static u32 avg_flip_cycles = 0; +static u32 avg_eval_cycles = 0; +static u32 avg_input_cycles = 0; +static u32 avg_mix_cycles = 0; +static u32 avg_frame_cycles = 0; + +#if PROF_ENABLE == 1 #define FRAME_START()\ do { \ - frame_cycles = 0;\ + if (prof_frame_counter == PROF_N_FRAMES) {\ + avg_ppu_pixel_cycles = ppu_pixel_cycles / prof_frame_counter;\ + avg_ppu_fill_cycles = ppu_fill_cycles / prof_frame_counter;\ + avg_ppu_chr_cycles = ppu_chr_cycles / prof_frame_counter;\ + avg_ppu_icn_cycles = ppu_icn_cycles / prof_frame_counter;\ + avg_flip_cycles = flip_cycles / prof_frame_counter;\ + avg_eval_cycles = eval_cycles / prof_frame_counter;\ + avg_input_cycles = input_cycles / prof_frame_counter;\ + avg_mix_cycles = mix_cycles / prof_frame_counter;\ + avg_frame_cycles = frame_cycles / prof_frame_counter;\ + prof_frame_counter = 0;\ + frame_cycles = 0;\ + ppu_pixel_cycles = 0;\ + ppu_fill_cycles = 0;\ + ppu_chr_cycles = 0;\ + ppu_icn_cycles = 0;\ + flip_cycles = 0;\ + eval_cycles = 0;\ + input_cycles = 0;\ + mix_cycles = 0;\ + }\ profile_start();\ } while (0) -#define FRAME_END() (frame_cycles = profile_stop()) +#elif PROF_ENABLE == 2 +#define FRAME_START()\ + do { \ + if (prof_frame_counter == PROF_N_FRAMES) {\ + avg_ppu_pixel_cycles = ppu_pixel_cycles;\ + avg_ppu_fill_cycles = ppu_fill_cycles;\ + avg_ppu_chr_cycles = ppu_chr_cycles;\ + avg_ppu_icn_cycles = ppu_icn_cycles;\ + avg_flip_cycles = flip_cycles;\ + avg_eval_cycles = eval_cycles;\ + avg_input_cycles = input_cycles;\ + avg_mix_cycles = mix_cycles;\ + avg_frame_cycles = frame_cycles / prof_frame_counter;\ + prof_frame_counter = 0;\ + frame_cycles = 0;\ + ppu_pixel_cycles = 0;\ + ppu_fill_cycles = 0;\ + ppu_chr_cycles = 0;\ + ppu_icn_cycles = 0;\ + flip_cycles = 0;\ + eval_cycles = 0;\ + input_cycles = 0;\ + mix_cycles = 0;\ + }\ + profile_start();\ + } while (0) +#endif + +#define FRAME_END() \ + do { \ + prof_frame_counter++;\ + frame_cycles += profile_stop();\ + } while (0) + #else + +// No profiling. #define PROF(F,VAR) (F) #define PROF_SHOW() +#define FRAME_START() +#define FRAME_END() #endif static time_t seconds = 0; @@ -646,8 +725,9 @@ main(void) { // NOTE: A VBLANK is 83776 cycles, anything other than that will make it so // we fail to render at 60FPS. while(true) { - FRAME_START(); + PROF_SHOW(); bios_vblank_wait(); + FRAME_START(); PROF(handle_input(&u), input_cycles); PROF(uxn_eval(&u, PEEK2(&u.dev[0x20])), eval_cycles); PROF(sound_mix(), mix_cycles); @@ -660,7 +740,6 @@ main(void) { frame_counter = 0; } FRAME_END(); - PROF_SHOW(); } return 0; -- cgit v1.2.1