From 1db92cb6b3db5965a52359cb2dab7ebd3f476f53 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 13 Oct 2011 13:43:36 +0200 Subject: [PATCH] Add completion latency percentiles to terse output format Signed-off-by: Jens Axboe --- HOWTO | 9 ++++++++ fio.1 | 8 +++++++ stat.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 74 insertions(+), 13 deletions(-) diff --git a/HOWTO b/HOWTO index 11ade8c1..a0d244bc 100644 --- a/HOWTO +++ b/HOWTO @@ -1365,12 +1365,14 @@ Split up, the format is as follows: Total IO (KB), bandwidth (KB/sec), IOPS, runtime (msec) Submission latency: min, max, mean, deviation Completion latency: min, max, mean, deviation + Completion latency percentiles: 20 fields (see below) Total latency: min, max, mean, deviation Bw: min, max, aggregate percentage of total, mean, deviation WRITE status: Total IO (KB), bandwidth (KB/sec), IOPS, runtime (msec) Submission latency: min, max, mean, deviation Completion latency: min, max, mean, deviation + Completion latency percentiles: 20 fields (see below) Total latency: min, max, mean, deviation Bw: min, max, aggregate percentage of total, mean, deviation CPU usage: user, system, context switches, major faults, minor faults @@ -1381,6 +1383,13 @@ Split up, the format is as follows: Additional Info (dependant on description being set): Text description +Completion latency percentiles can be a grouping of up to 20 sets, so +for the terse output fio writes all of them. Each field will look like this: + + 1.00%=6112 + +which is the Xth percentile, and the usec latency associated with it. + 8.0 Trace file format --------------------- diff --git a/fio.1 b/fio.1 index 0cf12fc4..ce08ff2b 100644 --- a/fio.1 +++ b/fio.1 @@ -1114,6 +1114,10 @@ Completion latency: .RS .B min, max, mean, standard deviation .RE +Completion latency percentiles (20 fields): +.RS +.B Xth percentile=usec +.RE Total latency: .RS .B min, max, mean, standard deviation @@ -1136,6 +1140,10 @@ Completion latency: .RS .B min, max, mean, standard deviation .RE +Completion latency percentiles (20 fields): +.RS +.B Xth percentile=usec +.RE Total latency: .RS .B min, max, mean, standard deviation diff --git a/stat.c b/stat.c index f399e912..1c4491bd 100644 --- a/stat.c +++ b/stat.c @@ -114,23 +114,27 @@ static int double_cmp(const void *a, const void *b) return cmp; } -/* - * Find and display the p-th percentile of clat - */ -static void show_clat_percentiles(unsigned int *io_u_plat, unsigned long nr, - fio_fp64_t *plist) +static unsigned int calc_clat_percentiles(unsigned int *io_u_plat, + unsigned long nr, fio_fp64_t *plist, + unsigned int **output, + unsigned int *maxv, + unsigned int *minv) { unsigned long sum = 0; - unsigned int len, i, j = 0, minv = -1U, maxv = 0; - unsigned int *ovals = NULL, oval_len = 0; - int is_last, scale_down; + unsigned int len, i, j = 0; + unsigned int oval_len = 0; + unsigned int *ovals = NULL; + int is_last; + + *minv = -1U; + *maxv = 0; len = 0; while (len < FIO_IO_U_LIST_MAX_LEN && plist[len].u.f != 0.0) len++; if (!len) - return; + return 0; /* * Sort the percentile list. Note that it may already be sorted if @@ -155,10 +159,10 @@ static void show_clat_percentiles(unsigned int *io_u_plat, unsigned long nr, } ovals[j] = plat_idx_to_val(i); - if (ovals[j] < minv) - minv = ovals[j]; - if (ovals[j] > maxv) - maxv = ovals[j]; + if (ovals[j] < *minv) + *minv = ovals[j]; + if (ovals[j] > *maxv) + *maxv = ovals[j]; is_last = (j == len - 1); if (is_last) @@ -168,6 +172,24 @@ static void show_clat_percentiles(unsigned int *io_u_plat, unsigned long nr, } } + *output = ovals; + return len; +} + +/* + * Find and display the p-th percentile of clat + */ +static void show_clat_percentiles(unsigned int *io_u_plat, unsigned long nr, + fio_fp64_t *plist) +{ + unsigned int len, j = 0, minv, maxv; + unsigned int *ovals; + int is_last, scale_down; + + len = calc_clat_percentiles(io_u_plat, nr, plist, &ovals, &maxv, &minv); + if (!len) + goto out; + /* * We default to usecs, but if the value range is such that we * should scale down to msecs, do that. @@ -207,6 +229,7 @@ static void show_clat_percentiles(unsigned int *io_u_plat, unsigned long nr, log_info("\n"); } +out: if (ovals) free(ovals); } @@ -559,7 +582,10 @@ static void show_ddir_status_terse(struct thread_stat *ts, { unsigned long min, max; unsigned long long bw, iops; + unsigned int *ovals = NULL; double mean, dev; + unsigned int len, minv, maxv; + int i; assert(ddir_rw(ddir)); @@ -589,6 +615,24 @@ static void show_ddir_status_terse(struct thread_stat *ts, else log_info(";%lu;%lu;%f;%f", 0UL, 0UL, 0.0, 0.0); + if (ts->clat_percentiles) { + len = calc_clat_percentiles(ts->io_u_plat[ddir], + ts->clat_stat[ddir].samples, + ts->percentile_list, &ovals, &maxv, + &minv); + } else + len = 0; + + for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) { + if (i >= len) { + log_info(";0%%=0"); + continue; + } + log_info(";%2.2f%%=%u", ts->percentile_list[i].u.f, ovals[i]); + } + if (ovals) + free(ovals); + if (calc_lat(&ts->bw_stat[ddir], &min, &max, &mean, &dev)) { double p_of_agg; -- 2.25.1