From: Jens Axboe Date: Fri, 21 Feb 2014 21:55:31 +0000 (-0800) Subject: Improve latency_target runs X-Git-Tag: fio-2.1.6~19 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=6bb58215842760895071d9f331da4dc2dfc16f30;hp=e4668264df255e8d01680920a4e78fd4186aeff1 Improve latency_target runs Reset the stats when we have found our target, and then do another latency_window run with those settings so that the final results reflect the probed values. Signed-off-by: Jens Axboe --- diff --git a/fio.h b/fio.h index d1180cd4..9159b0c2 100644 --- a/fio.h +++ b/fio.h @@ -262,6 +262,7 @@ struct thread_data { unsigned int latency_qd_low; unsigned int latency_failed; uint64_t latency_ios; + int latency_end_run; /* * read/write mixed workload state @@ -504,6 +505,7 @@ extern int load_blktrace(struct thread_data *, const char *, int); */ extern void lat_target_check(struct thread_data *); extern void lat_target_init(struct thread_data *); +extern void lat_target_reset(struct thread_data *); #define for_each_td(td, i) \ for ((i) = 0, (td) = &threads[0]; (i) < (int) thread_number; (i)++, (td)++) diff --git a/io_u.c b/io_u.c index b84b3e23..619fa252 100644 --- a/io_u.c +++ b/io_u.c @@ -1162,6 +1162,10 @@ static int __lat_target_failed(struct thread_data *td) return 1; td->latency_qd_high = td->latency_qd; + + if (td->latency_qd == td->latency_qd_low) + td->latency_qd_low--; + td->latency_qd = (td->latency_qd + td->latency_qd_low) / 2; dprint(FD_RATE, "Ramped down: %d %d %d\n", td->latency_qd_low, td->latency_qd, td->latency_qd_high); @@ -1186,6 +1190,8 @@ static int lat_target_failed(struct thread_data *td) void lat_target_init(struct thread_data *td) { + td->latency_end_run = 0; + if (td->o.latency_target) { dprint(FD_RATE, "Latency target=%llu\n", td->o.latency_target); fio_gettime(&td->latency_ts, NULL); @@ -1197,9 +1203,16 @@ void lat_target_init(struct thread_data *td) td->latency_qd = td->o.iodepth; } +void lat_target_reset(struct thread_data *td) +{ + if (!td->latency_end_run) + lat_target_init(td); +} + static void lat_target_success(struct thread_data *td) { const unsigned int qd = td->latency_qd; + struct thread_options *o = &td->o; td->latency_qd_low = td->latency_qd; @@ -1208,20 +1221,32 @@ static void lat_target_success(struct thread_data *td) * of bisecting from highest possible queue depth. If we have set * a limit other than td->o.iodepth, bisect between that. */ - if (td->latency_qd_high != td->o.iodepth) + if (td->latency_qd_high != o->iodepth) td->latency_qd = (td->latency_qd + td->latency_qd_high) / 2; else td->latency_qd *= 2; - if (td->latency_qd > td->o.iodepth) - td->latency_qd = td->o.iodepth; + if (td->latency_qd > o->iodepth) + td->latency_qd = o->iodepth; dprint(FD_RATE, "Ramped up: %d %d %d\n", td->latency_qd_low, td->latency_qd, td->latency_qd_high); + /* - * Same as last one, we are done + * Same as last one, we are done. Let it run a latency cycle, so + * we get only the results from the targeted depth. */ - if (td->latency_qd == qd) - td->done = 1; + if (td->latency_qd == qd) { + if (td->latency_end_run) { + dprint(FD_RATE, "We are done\n"); + td->done = 1; + } else { + dprint(FD_RATE, "Quiesce and final run\n"); + io_u_quiesce(td); + td->latency_end_run = 1; + reset_all_stats(td); + reset_io_stats(td); + } + } lat_new_cycle(td); } diff --git a/libfio.c b/libfio.c index 222cd16d..f4aac2ef 100644 --- a/libfio.c +++ b/libfio.c @@ -135,7 +135,7 @@ void reset_all_stats(struct thread_data *td) memcpy(&td->epoch, &tv, sizeof(tv)); memcpy(&td->start, &tv, sizeof(tv)); - lat_target_init(td); + lat_target_reset(td); } void reset_fio_state(void) diff --git a/stat.c b/stat.c index bc01b519..e43db8f9 100644 --- a/stat.c +++ b/stat.c @@ -1579,6 +1579,41 @@ static inline void reset_io_stat(struct io_stat *ios) ios->mean.u.f = ios->S.u.f = 0; } +void reset_io_stats(struct thread_data *td) +{ + struct thread_stat *ts = &td->ts; + int i, j; + + for (i = 0; i < DDIR_RWDIR_CNT; i++) { + reset_io_stat(&ts->clat_stat[i]); + reset_io_stat(&ts->slat_stat[i]); + reset_io_stat(&ts->lat_stat[i]); + reset_io_stat(&ts->bw_stat[i]); + reset_io_stat(&ts->iops_stat[i]); + + ts->io_bytes[i] = 0; + ts->runtime[i] = 0; + + for (j = 0; j < FIO_IO_U_PLAT_NR; j++) + ts->io_u_plat[i][j] = 0; + } + + for (i = 0; i < FIO_IO_U_MAP_NR; i++) { + ts->io_u_map[i] = 0; + ts->io_u_submit[i] = 0; + ts->io_u_complete[i] = 0; + ts->io_u_lat_u[i] = 0; + ts->io_u_lat_m[i] = 0; + ts->total_submit = 0; + ts->total_complete = 0; + } + + for (i = 0; i < 3; i++) { + ts->total_io_u[i] = 0; + ts->short_io_u[i] = 0; + } +} + static void _add_stat_to_log(struct io_log *iolog, unsigned long elapsed) { /* diff --git a/stat.h b/stat.h index 7ad0c9df..bc4f6da4 100644 --- a/stat.h +++ b/stat.h @@ -224,6 +224,7 @@ extern unsigned int calc_clat_percentiles(unsigned int *io_u_plat, unsigned long extern void stat_calc_lat_m(struct thread_stat *ts, double *io_u_lat); extern void stat_calc_lat_u(struct thread_stat *ts, double *io_u_lat); extern void stat_calc_dist(unsigned int *map, unsigned long total, double *io_u_dist); +extern void reset_io_stats(struct thread_data *); static inline int usec_to_msec(unsigned long *min, unsigned long *max, double *mean, double *dev)