From a13ad841db8420374e8ba1ad6f11bbd1c28af70c Mon Sep 17 00:00:00 2001 From: goksu <25721443+goeksu@users.noreply.github.com> Date: Tue, 29 Aug 2023 10:25:11 +0300 Subject: [PATCH] timer fix --- builds/testing.mk | 2 +- src/tools/ftbench/ftbench.c | 157 +++++++++----------------------- src/tools/ftbench/src/tohtml.py | 14 +-- 3 files changed, 49 insertions(+), 124 deletions(-) diff --git a/builds/testing.mk b/builds/testing.mk index 55288e4af..3da038804 100644 --- a/builds/testing.mk +++ b/builds/testing.mk @@ -3,7 +3,7 @@ FTBENCH_DIR = $(TOP_DIR)/src/tools/ftbench FTBENCH_SRC = $(FTBENCH_DIR)/ftbench.c FTBENCH_OBJ = $(OBJ_DIR)/bench.$(SO) FTBENCH_BIN = $(OBJ_DIR)/bench$E -FTBENCH_FLAG ?= -c 550 -w 50 +FTBENCH_FLAG ?= -c 750 -w 50 INCLUDES = $(TOP_DIR)/include FONTS = $(wildcard $(FTBENCH_DIR)/fonts/*.ttf) BASELINE_DIR = $(OBJ_DIR)/baseline/ diff --git a/src/tools/ftbench/ftbench.c b/src/tools/ftbench/ftbench.c index cb8be7efc..95b6d5da2 100644 --- a/src/tools/ftbench/ftbench.c +++ b/src/tools/ftbench/ftbench.c @@ -66,8 +66,7 @@ typedef int - (*bcall_t)( btimer_t* timer, - FT_Face face, + (*bcall_t)( FT_Face face, void* user_data ); @@ -260,7 +259,7 @@ #define TIMER_GET( timer ) ( timer )->total #define TIMER_RESET( timer ) ( timer )->total = 0 -#define CHUNK_SIZE 100 +#define CHUNK_SIZE 50 int compare(const void* a, const void* b) { if (*(double*)a > *(double*)b) return 1; @@ -271,53 +270,44 @@ int compare(const void* a, const void* b) { static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time, double warmup) { int n, done; int total_done = 0; // track total iterations done across all chunks - btimer_t timer, elapsed; + double total_time = 0.0; + btimer_t timer; int NUM_CHUNKS = max_iter / CHUNK_SIZE; double medians[NUM_CHUNKS]; - double errors[NUM_CHUNKS]; - if (test->cache_first) { - TIMER_RESET(&timer); - test->bench(&timer, face, test->user_data); + // Cache and warmup + if (test->cache_first) { + TIMER_START(&timer); + for(int i = 0; i<1+warmup; i++) + test->bench(face, test->user_data); + TIMER_STOP(&timer); } - - // Initial warm-up - for (n = 0; n < warmup; n++) { - test->bench(&timer, face, test->user_data); - } - + printf(" %-25s ", test->title); fflush(stdout); for (int chunk = 0; chunk < NUM_CHUNKS; chunk++) { - double chunk_results[CHUNK_SIZE]; TIMER_RESET(&timer); - TIMER_RESET(&elapsed); + TIMER_START(&timer); // Execute a chunk of iterations - for (n = 0, done = 0; n < CHUNK_SIZE; n++) { - TIMER_START(&elapsed); - done += test->bench(&timer, face, test->user_data); - TIMER_STOP(&elapsed); - chunk_results[n] = TIMER_GET(&elapsed); - - // Check max_time for each iteration, break if exceeded - if (TIMER_GET(&elapsed) > 1E6 * max_time) { - break; - } + for (n = 0, done = 0; n < CHUNK_SIZE; n++) { + done += test->bench(face, test->user_data); } + TIMER_STOP(&timer); + medians[chunk] = TIMER_GET(&timer); + + + total_time += medians[chunk]; total_done += done; - qsort(chunk_results, CHUNK_SIZE, sizeof(double), compare); - if (CHUNK_SIZE % 2 == 0) { - medians[chunk] = (chunk_results[CHUNK_SIZE / 2 - 1] + chunk_results[CHUNK_SIZE / 2]) / 2.0; - } else { - medians[chunk] = chunk_results[CHUNK_SIZE / 2]; - } - errors[chunk] = chunk_results[91 * CHUNK_SIZE / 100] - chunk_results[10 * CHUNK_SIZE / 100]; + // Check max_time for each iteration, break if exceeded + if (total_time > 1E6 * max_time) + break; + } - + qsort(medians, NUM_CHUNKS, sizeof(double), compare); double final_median; if (NUM_CHUNKS % 2 == 0) { @@ -326,7 +316,7 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time final_median = medians[NUM_CHUNKS / 2]; } - printf("%10.1f microseconds %10d done\n", final_median, total_done); + printf("%10.1f microseconds %10d done\n", final_median/CHUNK_SIZE, total_done); } /* @@ -334,8 +324,7 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time */ static int - test_load( btimer_t* timer, - FT_Face face, + test_load( FT_Face face, void* user_data ) { int i, done = 0; @@ -343,23 +332,18 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time FT_UNUSED( user_data ); - TIMER_START( timer ); - FOREACH( i ) { if ( !FT_Load_Glyph( face, (FT_UInt)i, load_flags ) ) done++; } - TIMER_STOP( timer ); - return done; } static int - test_load_advances( btimer_t* timer, - FT_Face face, + test_load_advances( FT_Face face, void* user_data ) { int done = 0; @@ -381,15 +365,11 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time advances = (FT_Fixed *)calloc( sizeof ( FT_Fixed ), (size_t)count ); - TIMER_START( timer ); - FT_Get_Advances( face, (FT_UInt)start, (FT_UInt)count, (FT_Int32)flags, advances ); done += (int)count; - TIMER_STOP( timer ); - free( advances ); return done; @@ -397,8 +377,7 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time static int - test_render( btimer_t* timer, - FT_Face face, + test_render( FT_Face face, void* user_data ) { int i, done = 0; @@ -411,10 +390,8 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time if ( FT_Load_Glyph( face, (FT_UInt)i, load_flags ) ) continue; - TIMER_START( timer ); if ( !FT_Render_Glyph( face->glyph, render_mode ) ) done++; - TIMER_STOP( timer ); } return done; @@ -422,8 +399,7 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time static int - test_embolden( btimer_t* timer, - FT_Face face, + test_embolden( FT_Face face, void* user_data ) { int i, done = 0; @@ -436,10 +412,8 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time if ( FT_Load_Glyph( face, (FT_UInt)i, load_flags ) ) continue; - TIMER_START( timer ); FT_GlyphSlot_Embolden( face->glyph ); done++; - TIMER_STOP( timer ); } return done; @@ -447,8 +421,7 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time static int - test_stroke( btimer_t* timer, - FT_Face face, + test_stroke( FT_Face face, void* user_data ) { FT_Glyph glyph; @@ -472,9 +445,7 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time FT_Get_Glyph( face->glyph, &glyph ) ) continue; - TIMER_START( timer ); FT_Glyph_Stroke( &glyph, stroker, 1 ); - TIMER_STOP( timer ); FT_Done_Glyph( glyph ); done++; @@ -487,8 +458,7 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time static int - test_get_glyph( btimer_t* timer, - FT_Face face, + test_get_glyph( FT_Face face, void* user_data ) { FT_Glyph glyph; @@ -503,13 +473,11 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time if ( FT_Load_Glyph( face, (FT_UInt)i, load_flags ) ) continue; - TIMER_START( timer ); if ( !FT_Get_Glyph( face->glyph, &glyph ) ) { FT_Done_Glyph( glyph ); done++; } - TIMER_STOP( timer ); } return done; @@ -517,8 +485,7 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time static int - test_get_cbox( btimer_t* timer, - FT_Face face, + test_get_cbox( FT_Face face, void* user_data ) { FT_Glyph glyph; @@ -537,10 +504,8 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time if ( FT_Get_Glyph( face->glyph, &glyph ) ) continue; - TIMER_START( timer ); FT_Glyph_Get_CBox( glyph, FT_GLYPH_BBOX_PIXELS, &bbox ); - TIMER_STOP( timer ); - + FT_Done_Glyph( glyph ); done++; } @@ -550,8 +515,7 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time static int - test_get_bbox( btimer_t* timer, - FT_Face face, + test_get_bbox( FT_Face face, void* user_data ) { FT_BBox bbox; @@ -566,9 +530,7 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time if ( FT_Load_Glyph( face, (FT_UInt)i, load_flags ) ) continue; - TIMER_START( timer ); FT_Outline_Get_BBox( &face->glyph->outline, &bbox ); - TIMER_STOP( timer ); done++; } @@ -578,31 +540,25 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time static int - test_get_char_index( btimer_t* timer, - FT_Face face, + test_get_char_index( FT_Face face, void* user_data ) { bcharset_t* charset = (bcharset_t*)user_data; int i, done = 0; - TIMER_START( timer ); - for ( i = 0; i < charset->size; i++ ) { if ( FT_Get_Char_Index(face, charset->code[i]) ) done++; } - TIMER_STOP( timer ); - return done; } static int - test_cmap_cache( btimer_t* timer, - FT_Face face, + test_cmap_cache( FT_Face face, void* user_data ) { bcharset_t* charset = (bcharset_t*)user_data; @@ -611,8 +567,6 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time FT_UNUSED( face ); - TIMER_START( timer ); - for ( i = 0; i < charset->size; i++ ) { if ( FTC_CMapCache_Lookup( cmap_cache, @@ -622,15 +576,12 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time done++; } - TIMER_STOP( timer ); - return done; } static int - test_image_cache( btimer_t* timer, - FT_Face face, + test_image_cache( FT_Face face, void* user_data ) { FT_Glyph glyph; @@ -640,9 +591,6 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time FT_UNUSED( face ); FT_UNUSED( user_data ); - - TIMER_START( timer ); - FOREACH( i ) { if ( !FTC_ImageCache_Lookup( image_cache, @@ -653,15 +601,12 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time done++; } - TIMER_STOP( timer ); - return done; } static int - test_sbit_cache( btimer_t* timer, - FT_Face face, + test_sbit_cache( FT_Face face, void* user_data ) { FTC_SBit glyph; @@ -671,9 +616,6 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time FT_UNUSED( face ); FT_UNUSED( user_data ); - - TIMER_START( timer ); - FOREACH( i ) { if ( !FTC_SBitCache_Lookup( sbit_cache, @@ -684,15 +626,12 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time done++; } - TIMER_STOP( timer ); - return done; } static int - test_cmap_iter( btimer_t* timer, - FT_Face face, + test_cmap_iter( FT_Face face, void* user_data ) { FT_UInt idx; @@ -702,23 +641,18 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time FT_UNUSED( user_data ); - TIMER_START( timer ); - charcode = FT_Get_First_Char( face, &idx ); done = ( idx != 0 ); while ( idx != 0 ) charcode = FT_Get_Next_Char( face, charcode, &idx ); - TIMER_STOP( timer ); - return done; } static int - test_new_face( btimer_t* timer, - FT_Face face, + test_new_face( FT_Face face, void* user_data ) { FT_Face bench_face; @@ -727,20 +661,15 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time FT_UNUSED( user_data ); - TIMER_START( timer ); - if ( !get_face( &bench_face ) ) FT_Done_Face( bench_face ); - TIMER_STOP( timer ); - return 1; } static int - test_new_face_and_load_glyph( btimer_t* timer, - FT_Face face, + test_new_face_and_load_glyph( FT_Face face, void* user_data ) { FT_Face bench_face; @@ -751,8 +680,6 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time FT_UNUSED( user_data ); - TIMER_START( timer ); - if ( !get_face( &bench_face ) ) { FOREACH( i ) @@ -764,8 +691,6 @@ static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time FT_Done_Face( bench_face ); } - TIMER_STOP( timer ); - return done; } diff --git a/src/tools/ftbench/src/tohtml.py b/src/tools/ftbench/src/tohtml.py index 61205a671..0917b203b 100644 --- a/src/tools/ftbench/src/tohtml.py +++ b/src/tools/ftbench/src/tohtml.py @@ -108,7 +108,7 @@ def generate_info_table(html_file, baseline_info, benchmark_info): ), ) write_to_html(html_file, "
") - write_to_html(html_file, "

* Average time for all iterations. Smaller values are better.

") + write_to_html(html_file, "

* Average time for single iteration. Smaller values are better.

") write_to_html(html_file, "

** N count in (x | y) format is for showing baseline and benchmark N counts seperately when they differs.

") @@ -181,8 +181,8 @@ def generate_total_results_table(html_file, baseline_dir, benchmark_dir): write_to_html( html_file, f'{test}{n_display}\ - {baseline:.0f}\ - {benchmark:.0f}{diff:.1f}\n' + {baseline:.1f}\ + {benchmark:.1f}{diff:.1f}\n' ) total_diff = ((total_baseline - total_benchmark) / total_baseline) * 100 @@ -191,7 +191,7 @@ def generate_total_results_table(html_file, baseline_dir, benchmark_dir): write_to_html( html_file, f'TOTAL{total_n_display}\ - {total_baseline:.0f}{total_benchmark:.0f}\ + {total_baseline:.1f}{total_benchmark:.1f}\ {total_diff:.1f}\n' ) @@ -258,7 +258,7 @@ def generate_results_table(html_file, baseline_results, benchmark_results, filen write_to_html( html_file, '{}{}\ - {:.0f}{:.0f}{:.1f}\n'.format( + {:.1f}{:.1f}{:.1f}\n'.format( baseline_match.group(1), n, baseline_value, @@ -270,7 +270,7 @@ def generate_results_table(html_file, baseline_results, benchmark_results, filen write_to_html( html_file, '{}{}\ - {:.0f}{:.0f}{:.1f}\n'.format( + {:.1f}{:.1f}{:.1f}\n'.format( baseline_match.group(1), n, baseline_value, @@ -282,7 +282,7 @@ def generate_results_table(html_file, baseline_results, benchmark_results, filen write_to_html( html_file, 'TOTAL{}\ - {:.0f}{:.0f}{:.1f}\n'.format( + {:.1f}{:.1f}{:.1f}\n'.format( total_n, total_time_baseline, total_time_benchmark, (total_time_baseline - total_time_benchmark) / total_time_baseline * -100 ), )