summaryrefslogtreecommitdiff
path: root/perf
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-06-11 11:05:03 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-06-11 11:30:43 +0100
commit9a12c2e02369f0920c1f1f578eb8d228add77ea1 (patch)
treea8c0e8772c894d06f8030813ea9c7bd85577c5fd /perf
parente519d6f9860c7f0bc51f1e8a17505f2dc372c938 (diff)
downloadcairo-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.c65
-rw-r--r--perf/cairo-perf-report.c2
-rw-r--r--perf/cairo-perf.h9
-rw-r--r--perf/cairo-stats.c80
-rw-r--r--perf/cairo-stats.h16
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_ */