timer fix

This commit is contained in:
goksu 2023-08-29 10:25:11 +03:00
parent f3dfede62f
commit a13ad841db
No known key found for this signature in database
3 changed files with 49 additions and 124 deletions

View File

@ -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/

View File

@ -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;
}

View File

@ -108,7 +108,7 @@ def generate_info_table(html_file, baseline_info, benchmark_info):
),
)
write_to_html(html_file, "</table><br/>")
write_to_html(html_file, "<p>* Average time for all iterations. Smaller values are better.</p>")
write_to_html(html_file, "<p>* Average time for single iteration. Smaller values are better.</p>")
write_to_html(html_file, "<p>** N count in (x | y) format is for showing baseline and benchmark N counts seperately when they differs.</p>")
@ -181,8 +181,8 @@ def generate_total_results_table(html_file, baseline_dir, benchmark_dir):
write_to_html(
html_file,
f'<tr><td class="col1">{test}</td><td>{n_display}</td>\
<td class="{baseline_color}">{baseline:.0f}</td>\
<td class="{benchmark_color}">{benchmark:.0f}</td><td>{diff:.1f}</td></tr>\n'
<td class="{baseline_color}">{baseline:.1f}</td>\
<td class="{benchmark_color}">{benchmark:.1f}</td><td>{diff:.1f}</td></tr>\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'<tr><td class="col1">TOTAL</td><td class="col1">{total_n_display}</td>\
<td class="col1">{total_baseline:.0f}</td><td class="col1">{total_benchmark:.0f}</td>\
<td class="col1">{total_baseline:.1f}</td><td class="col1">{total_benchmark:.1f}</td>\
<td class="col1">{total_diff:.1f}</td></tr>\n'
)
@ -258,7 +258,7 @@ def generate_results_table(html_file, baseline_results, benchmark_results, filen
write_to_html(
html_file,
'<tr><td class="col1">{}</td><td>{}</td>\
<td class="lowlight">{:.0f}</td><td class="highlight">{:.0f}</td><td>{:.1f}</td></tr>\n'.format(
<td class="lowlight">{:.1f}</td><td class="highlight">{:.1f}</td><td>{:.1f}</td></tr>\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,
'<tr><td class="col1">{}</td><td>{}</td>\
<td class="highlight">{:.0f}</td><td class="lowlight">{:.0f}</td><td>{:.1f}</td></tr>\n'.format(
<td class="highlight">{:.1f}</td><td class="lowlight">{:.1f}</td><td>{:.1f}</td></tr>\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,
'<tr><td class="col1">TOTAL</td><td class="col1">{}</td>\
<td class="col1">{:.0f}</td><td class="col1">{:.0f}</td><td class="col1">{:.1f}</td></tr>\n'.format(
<td class="col1">{:.1f}</td><td class="col1">{:.1f}</td><td class="col1">{:.1f}</td></tr>\n'.format(
total_n, total_time_baseline, total_time_benchmark, (total_time_baseline - total_time_benchmark) / total_time_baseline * -100
),
)