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);
- }
-
- // Initial warm-up
- for (n = 0; n < warmup; n++) {
- 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);
}
-
+
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'