diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-06-11 11:05:03 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-06-11 11:30:43 +0100 |
commit | 9a12c2e02369f0920c1f1f578eb8d228add77ea1 (patch) | |
tree | a8c0e8772c894d06f8030813ea9c7bd85577c5fd /perf | |
parent | e519d6f9860c7f0bc51f1e8a17505f2dc372c938 (diff) | |
download | cairo-9a12c2e02369f0920c1f1f578eb8d228add77ea1.tar.gz |
perf: Rudimentary histogram printing for cairo-perf-print
If you call ./cairo-perf-print --histogram results.txt, it will then
print a histogram of the results, one per test. Ideally, you should see
a skewed distribution (with a negative skew representing that most results
run in optimal time), but random sampling errors (scheduling,
throttling, general inefficiency etc) will push it more towards a normal
distribution.
For example,
| x |
| x xx |
| x xx |
| x xx |
| xxxx |
| xxxx x |
| x xxxxxx |
| x xxxxxx |
| xxxxxxxxx |
| xxxxxxxxx |
| xxxxxxxxx |
| xxxxxxxxxxxx |
| xxxxxxxxxxxx |
| xxxxxxxxxxxx |
| xxxxxxxxxxxxxx |
|x xxxxxxxxxxxxxx |
|x x xxxxxxxxxxxxxxx |
|x x xxxxxxxxxxxxxxx |
|x x xxxxxxxxxxxxxxxxx |
|xxx x xxxxxxxxxxxxxxxxxxx |
|xxx xxxxxxxxxxxxxxxxxxxxxxxxx |
|xxxxxx xxxx x x x x xxx xx xxxxx xxx x xxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
.------------------------------------------------------------------------------.
xlib firefox-fishtank 8298.44 1.53% (829/946)
Starts off reasonably, but quickly deteriorates as the integrated CPU/GPU
overheats and is forced to throttle.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'perf')
-rw-r--r-- | perf/cairo-perf-print.c | 65 | ||||
-rw-r--r-- | perf/cairo-perf-report.c | 2 | ||||
-rw-r--r-- | perf/cairo-perf.h | 9 | ||||
-rw-r--r-- | perf/cairo-stats.c | 80 | ||||
-rw-r--r-- | perf/cairo-stats.h | 16 |
5 files changed, 155 insertions, 17 deletions
diff --git a/perf/cairo-perf-print.c b/perf/cairo-perf-print.c index 16a3ff4b9..b6cf4ca01 100644 --- a/perf/cairo-perf-print.c +++ b/perf/cairo-perf-print.c @@ -28,45 +28,78 @@ */ #include "cairo-perf.h" +#include "cairo-stats.h" #include <stdio.h> static void -report_print (const cairo_perf_report_t *report) +report_print (const cairo_perf_report_t *report, + int show_histogram) { - const test_report_t *tests; + const test_report_t *test; + cairo_histogram_t h; - tests = report->tests; - for (tests = report->tests; tests->name != NULL; tests++) { - if (tests->stats.iterations == 0) + if (show_histogram && !_cairo_histogram_init (&h, 80, 23)) + show_histogram = 0; + + for (test = report->tests; test->name != NULL; test++) { + if (test->stats.iterations == 0) continue; - if (tests->size) { - printf ("%5s-%-4s %26s-%-3d %6.2f %4.2f%%\n", - tests->backend, tests->content, - tests->name, tests->size, - tests->stats.median_ticks / tests->stats.ticks_per_ms, - tests->stats.std_dev * 100); + if (show_histogram) { + const cairo_time_t *values; + int num_values; + + if (show_histogram > 1) { + values = test->stats.values; + num_values = test->stats.iterations; + } else { + values = test->samples; + num_values = test->samples_count; + } + + if (_cairo_histogram_compute (&h, values, num_values)) + _cairo_histogram_printf (&h, stdout); + } + + if (test->size) { + printf ("%5s-%-4s %26s-%-3d ", + test->backend, test->content, + test->name, test->size); } else { - printf ("%5s %26s %6.2f %4.2f%%\n", - tests->backend, tests->name, - tests->stats.median_ticks / tests->stats.ticks_per_ms, - tests->stats.std_dev * 100); + printf ("%5s %26s ", test->backend, test->name); } + printf("%6.2f %4.2f%% (%d/%d)\n", + test->stats.median_ticks / test->stats.ticks_per_ms, + test->stats.std_dev * 100, + test->stats.iterations, test->samples_count); } + + _cairo_histogram_fini (&h); } int main (int argc, const char *argv[]) { + cairo_bool_t show_histogram = 0; int i; for (i = 1; i < argc; i++ ) { cairo_perf_report_t report; + if (strcmp(argv[i], "--histogram") == 0) { + show_histogram = 1; + continue; + } + + if (strcmp(argv[i], "--short-histogram") == 0) { + show_histogram = 2; + continue; + } + cairo_perf_report_load (&report, argv[i], i, NULL); - report_print (&report); + report_print (&report, show_histogram); } return 0; diff --git a/perf/cairo-perf-report.c b/perf/cairo-perf-report.c index 38bdc0cd4..b86bc36f7 100644 --- a/perf/cairo-perf-report.c +++ b/perf/cairo-perf-report.c @@ -186,7 +186,7 @@ test_report_parse (test_report_t *report, skip_space (); } while (*s && *s != '\n'); report->stats.iterations = 0; - skip_char ('\n'); + if (*s) skip_char ('\n'); } else { parse_double (report->stats.min_ticks); skip_space (); diff --git a/perf/cairo-perf.h b/perf/cairo-perf.h index feab74be3..4e898acd7 100644 --- a/perf/cairo-perf.h +++ b/perf/cairo-perf.h @@ -38,8 +38,17 @@ typedef struct _cairo_stats { double ticks_per_ms; double std_dev; int iterations; + cairo_time_t *values; } cairo_stats_t; +typedef struct _cairo_histogram { + int width, height, max_count; + int num_columns, num_rows; + cairo_time_t min_value, max_value; + int *columns; +} cairo_histogram_t; + + /* timers */ void diff --git a/perf/cairo-stats.c b/perf/cairo-stats.c index 7a36a138f..c10c92192 100644 --- a/perf/cairo-stats.c +++ b/perf/cairo-stats.c @@ -43,6 +43,7 @@ _cairo_stats_compute (cairo_stats_t *stats, stats->min_ticks = stats->median_ticks = values[0]; stats->std_dev = 0; stats->iterations = 1; + stats->values = values; return; } @@ -80,6 +81,7 @@ _cairo_stats_compute (cairo_stats_t *stats, values += min_valid; } while (num_valid != num_values); + stats->values = values; stats->iterations = num_valid; stats->min_ticks = values[0]; stats->median_ticks = values[num_valid / 2]; @@ -97,3 +99,81 @@ _cairo_stats_compute (cairo_stats_t *stats, } stats->std_dev = sqrt(s / num_valid); } + +cairo_bool_t +_cairo_histogram_init (cairo_histogram_t *h, + int width, int height) +{ + h->width = width; + h->height = height; + if (h->width < 2 || h->height < 1) + return FALSE; + + h->num_columns = width - 2; + h->num_rows = height - 1; + h->columns = malloc (sizeof(int)*h->num_columns); + return h->columns != NULL; +} + +cairo_bool_t +_cairo_histogram_compute (cairo_histogram_t *h, + const cairo_time_t *values, + int num_values) +{ + cairo_time_t delta; + int i; + + if (num_values == 0) + return FALSE; + + h->min_value = values[0]; + h->max_value = values[0]; + + for (i = 1; i < num_values; i++) { + if (values[i] < h->min_value) + h->min_value = values[i]; + if (values[i] > h->max_value) + h->max_value = values[i]; + } + + delta = h->max_value - h->min_value; + if (delta == 0) + return FALSE; + + memset(h->columns, 0, sizeof(int)*h->num_columns); + h->max_count = 0; + + for (i = 0; i < num_values; i++) { + int count = h->columns[(values[i] - h->min_value) * (h->num_columns - 1) / delta]++; + if (count > h->max_count) + h->max_count = count; + } + + return TRUE; +} + +void +_cairo_histogram_printf (cairo_histogram_t *h, + FILE *file) +{ + int x, y; + + for (y = 0; y < h->num_rows; y++) { + int min_count = (h->num_rows - y - 1) * h->max_count / h->num_rows; + fprintf (file, "|"); + for (x = 0; x < h->num_columns; x++) + fprintf (file, "%c", h->columns[x] > min_count ? 'x' : ' '); + fprintf (file, "|\n"); + } + + fprintf(file, "."); + for (x = 0; x < h->num_columns; x++) + fprintf (file, "-"); + fprintf (file, ".\n"); +} + +void +_cairo_histogram_fini (cairo_histogram_t *h) +{ + free(h->columns); +} diff --git a/perf/cairo-stats.h b/perf/cairo-stats.h index 8406e6560..2b32d67ae 100644 --- a/perf/cairo-stats.h +++ b/perf/cairo-stats.h @@ -33,4 +33,20 @@ _cairo_stats_compute (cairo_stats_t *stats, cairo_time_t *values, int num_values); +cairo_bool_t +_cairo_histogram_init (cairo_histogram_t *h, + int width, int height); + +cairo_bool_t +_cairo_histogram_compute (cairo_histogram_t *h, + const cairo_time_t *values, + int num_values); + +void +_cairo_histogram_printf (cairo_histogram_t *h, + FILE *file); + +void +_cairo_histogram_fini (cairo_histogram_t *h); + #endif /* _CAIRO_STATS_H_ */ |