diff options
-rw-r--r-- | perf/cairo-perf.c | 71 |
1 files changed, 41 insertions, 30 deletions
diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c index b3afcd47..f2699feb 100644 --- a/perf/cairo-perf.c +++ b/perf/cairo-perf.c @@ -180,6 +180,42 @@ cairo_perf_can_run (cairo_perf_t *perf, return FALSE; } +static unsigned +cairo_perf_calibrate (cairo_perf_t *perf, + cairo_perf_func_t perf_func) +{ + cairo_perf_ticks_t calibration0, calibration; + unsigned loops, min_loops; + + calibration0 = perf_func (perf->cr, perf->size, perf->size, 1); + if (perf->fast_and_sloppy) { + calibration = calibration0; + } else { + loops = cairo_perf_ticks_per_second () / 100 / calibration0; + if (loops < 3) + loops = 3; + calibration = (calibration0 + perf_func (perf->cr, perf->size, perf->size, loops)) / (loops + 1); + } + + /* XXX + * Compute the number of loops required for the timing + * interval to be perf->ms_per_iteration milliseconds. This + * helps to eliminate sampling variance due to timing and + * other systematic errors. However, it also hides + * synchronisation overhead as we attempt to process a large + * batch of identical operations in a single shot. This can be + * considered both good and bad... It would be good to perform + * a more rigorous analysis of the synchronisation overhead, + * that is to estimate the time for loop=0. + */ + loops = perf->ms_per_iteration * 0.001 * cairo_perf_ticks_per_second () / calibration; + min_loops = perf->fast_and_sloppy ? 1 : 10; + if (loops < min_loops) + loops = min_loops; + + return loops; +} + void cairo_perf_run (cairo_perf_t *perf, const char *name, @@ -234,7 +270,6 @@ cairo_perf_run (cairo_perf_t *perf, has_similar = cairo_perf_has_similar (perf); for (similar = 0; similar <= has_similar; similar++) { - cairo_perf_ticks_t calibration0, calibration; unsigned loops; if (perf->summary) { @@ -252,32 +287,9 @@ cairo_perf_run (cairo_perf_t *perf, cairo_push_group_with_content (perf->cr, cairo_boilerplate_content (perf->target->content)); perf_func (perf->cr, perf->size, perf->size, 1); - calibration0 = perf_func (perf->cr, perf->size, perf->size, 1); - if (perf->fast_and_sloppy) { - calibration = calibration0; - } else { - loops = cairo_perf_ticks_per_second () / 100 / calibration0; - if (loops < 3) - loops = 3; - calibration = (calibration0 + perf_func (perf->cr, perf->size, perf->size, loops)) / (loops + 1); - if (similar) - cairo_pattern_destroy (cairo_pop_group (perf->cr)); - } - - /* XXX - * Compute the number of loops required for the timing - * interval to be perf->ms_per_iteration milliseconds. This - * helps to eliminate sampling variance due to timing and - * other systematic errors. However, it also hides - * synchronisation overhead as we attempt to process a large - * batch of identical operations in a single shot. This can be - * considered both good and bad... It would be good to perform - * a more rigorous analysis of the synchronisation overhead, - * that is to estimate the time for loop=0. - */ - loops = perf->ms_per_iteration * 0.001 * cairo_perf_ticks_per_second () / calibration; - if (loops < 10) - loops = perf->fast_and_sloppy ? 1 : 10; + loops = cairo_perf_calibrate (perf, perf_func); + if (similar) + cairo_pattern_destroy (cairo_pop_group (perf->cr)); low_std_dev_count = 0; for (i =0; i < perf->iterations; i++) { @@ -319,12 +331,11 @@ cairo_perf_run (cairo_perf_t *perf, if (perf->summary) { _cairo_stats_compute (&stats, times, i); fprintf (perf->summary, - "%10lld %#8.3f %#8.3f %#5.2f%% %3d %10lld\n", + "%10lld %#8.3f %#8.3f %#5.2f%% %3d\n", (long long) stats.min_ticks, (stats.min_ticks * 1000.0) / cairo_perf_ticks_per_second (), (stats.median_ticks * 1000.0) / cairo_perf_ticks_per_second (), - stats.std_dev * 100.0, stats.iterations, - (long long) (calibration0 - stats.min_ticks)); + stats.std_dev * 100.0, stats.iterations); fflush (perf->summary); } |