X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=stat.c;h=e72148b49ad0825f3e154bda0a1a303715f70764;hb=ae2fafc8525e980b8271e3230a0fd4da660fddda;hp=d54ed2cfeac3c1f4db320f9b913533527a666417;hpb=4d658652bac63fd72af8302e27deba5beb381906;p=fio.git diff --git a/stat.c b/stat.c index d54ed2cf..e72148b4 100644 --- a/stat.c +++ b/stat.c @@ -440,12 +440,14 @@ static void show_ddir_status(struct group_run_stats *rs, struct thread_stat *ts, ts->percentile_list); } if (calc_lat(&ts->bw_stat[ddir], &min, &max, &mean, &dev)) { - double p_of_agg; + double p_of_agg = 100.0; const char *bw_str = "KB"; - p_of_agg = mean * 100 / (double) rs->agg[ddir]; - if (p_of_agg > 100.0) - p_of_agg = 100.0; + if (rs->agg[ddir]) { + p_of_agg = mean * 100 / (double) rs->agg[ddir]; + if (p_of_agg > 100.0) + p_of_agg = 100.0; + } if (mean > 999999.9) { min /= 1000.0; @@ -628,11 +630,6 @@ static void show_ddir_status_terse(struct thread_stat *ts, else log_info(";%lu;%lu;%f;%f", 0UL, 0UL, 0.0, 0.0); - if (calc_lat(&ts->lat_stat[ddir], &min, &max, &mean, &dev)) - log_info(";%lu;%lu;%f;%f", min, max, mean, dev); - 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, @@ -648,13 +645,24 @@ static void show_ddir_status_terse(struct thread_stat *ts, } log_info(";%2.2f%%=%u", ts->percentile_list[i].u.f, ovals[i]); } + + if (calc_lat(&ts->lat_stat[ddir], &min, &max, &mean, &dev)) + log_info(";%lu;%lu;%f;%f", min, max, mean, dev); + else + log_info(";%lu;%lu;%f;%f", 0UL, 0UL, 0.0, 0.0); + if (ovals) free(ovals); if (calc_lat(&ts->bw_stat[ddir], &min, &max, &mean, &dev)) { - double p_of_agg; + double p_of_agg = 100.0; + + if (rs->agg[ddir]) { + p_of_agg = mean * 100 / (double) rs->agg[ddir]; + if (p_of_agg > 100.0) + p_of_agg = 100.0; + } - p_of_agg = mean * 100 / (double) rs->agg[ddir]; log_info(";%lu;%lu;%f%%;%f;%f", min, max, p_of_agg, mean, dev); } else log_info(";%lu;%lu;%f%%;%f;%f", 0UL, 0UL, 0.0, 0.0, 0.0); @@ -778,7 +786,7 @@ static void show_thread_status_terse_v3(struct thread_stat *ts, /* Additional output if description is set */ if (strlen(ts->description)) - log_info(";%s", ts->description); + log_info(";%s\n", ts->description); } static void show_thread_status_terse(struct thread_stat *ts, @@ -1127,6 +1135,9 @@ static void __add_log_sample(struct io_log *iolog, unsigned long val, { const int nr_samples = iolog->nr_samples; + if (!iolog->nr_samples) + iolog->avg_last = t; + if (iolog->nr_samples == iolog->max_samples) { int new_size = sizeof(struct io_sample) * iolog->max_samples*2; @@ -1141,14 +1152,66 @@ static void __add_log_sample(struct io_log *iolog, unsigned long val, iolog->nr_samples++; } +static inline void reset_io_stat(struct io_stat *ios) +{ + ios->max_val = ios->min_val = ios->samples = 0; + ios->mean.u.f = ios->S.u.f = 0; +} + static void add_log_sample(struct thread_data *td, struct io_log *iolog, unsigned long val, enum fio_ddir ddir, unsigned int bs) { + unsigned long elapsed, this_window; + if (!ddir_rw(ddir)) return; - __add_log_sample(iolog, val, ddir, bs, mtime_since_now(&td->epoch)); + elapsed = mtime_since_now(&td->epoch); + + /* + * If no time averaging, just add the log sample. + */ + if (!iolog->avg_msec) { + __add_log_sample(iolog, val, ddir, bs, elapsed); + return; + } + + /* + * Add the sample. If the time period has passed, then + * add that entry to the log and clear. + */ + add_stat_sample(&iolog->avg_window[ddir], val); + + /* + * If period hasn't passed, adding the above sample is all we + * need to do. + */ + this_window = elapsed - iolog->avg_last; + if (this_window < iolog->avg_msec) + return; + + /* + * Note an entry in the log. Use the mean from the logged samples, + * making sure to properly round up. Only write a log entry if we + * had actual samples done. + */ + if (iolog->avg_window[DDIR_READ].samples) { + unsigned long mr; + + mr = iolog->avg_window[DDIR_READ].mean.u.f + 0.50; + __add_log_sample(iolog, mr, DDIR_READ, 0, elapsed); + } + if (iolog->avg_window[DDIR_WRITE].samples) { + unsigned long mw; + + mw = iolog->avg_window[DDIR_WRITE].mean.u.f + 0.50; + __add_log_sample(iolog, mw, DDIR_WRITE, 0, elapsed); + } + + reset_io_stat(&iolog->avg_window[DDIR_READ]); + reset_io_stat(&iolog->avg_window[DDIR_WRITE]); + iolog->avg_last = elapsed; } void add_agg_sample(unsigned long val, enum fio_ddir ddir, unsigned int bs) @@ -1229,15 +1292,26 @@ void add_bw_sample(struct thread_data *td, enum fio_ddir ddir, unsigned int bs, if (spent < td->o.bw_avg_time) return; - rate = (td->this_io_bytes[ddir] - td->stat_io_bytes[ddir]) * - 1000 / spent / 1024; - add_stat_sample(&ts->bw_stat[ddir], rate); + /* + * Compute both read and write rates for the interval. + */ + for (ddir = DDIR_READ; ddir <= DDIR_WRITE; ddir++) { + uint64_t delta; + + delta = td->this_io_bytes[ddir] - td->stat_io_bytes[ddir]; + if (!delta) + continue; /* No entries for interval */ + + rate = delta * 1000 / spent / 1024; + add_stat_sample(&ts->bw_stat[ddir], rate); - if (td->bw_log) - add_log_sample(td, td->bw_log, rate, ddir, bs); + if (td->bw_log) + add_log_sample(td, td->bw_log, rate, ddir, bs); + + td->stat_io_bytes[ddir] = td->this_io_bytes[ddir]; + } fio_gettime(&td->bw_sample_time, NULL); - td->stat_io_bytes[ddir] = td->this_io_bytes[ddir]; } void add_iops_sample(struct thread_data *td, enum fio_ddir ddir, @@ -1253,15 +1327,24 @@ void add_iops_sample(struct thread_data *td, enum fio_ddir ddir, if (spent < td->o.iops_avg_time) return; - iops = ((td->this_io_blocks[ddir] - td->stat_io_blocks[ddir]) * 1000) / spent; + /* + * Compute both read and write rates for the interval. + */ + for (ddir = DDIR_READ; ddir <= DDIR_WRITE; ddir++) { + uint64_t delta; + + delta = td->this_io_blocks[ddir] - td->stat_io_blocks[ddir]; + if (!delta) + continue; /* No entries for interval */ + + iops = (delta * 1000) / spent; + add_stat_sample(&ts->iops_stat[ddir], iops); - add_stat_sample(&ts->iops_stat[ddir], iops); + if (td->iops_log) + add_log_sample(td, td->iops_log, iops, ddir, 0); - if (td->iops_log) { - assert(iops); - add_log_sample(td, td->iops_log, iops, ddir, 0); + td->stat_io_blocks[ddir] = td->this_io_blocks[ddir]; } fio_gettime(&td->iops_sample_time, NULL); - td->stat_io_blocks[ddir] = td->this_io_blocks[ddir]; }