[perf] Move the calibration to its own function

Improve code clarity and whatnot.
This commit is contained in:
Chris Wilson 2009-09-05 08:46:39 +01:00
parent 270b2f1be0
commit 9b932d7cd7

View file

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