From 721938ae7fae0f6d470a7e32e177ea5dce480229 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 10 Sep 2008 09:46:16 +0200 Subject: [PATCH] Add ramp_time option Sometimes it's useful to let a job settle for a little while before taking any measurements on latency and throughput, since the initial rate on eg a write workload may be much higher than the longer sustained rate. So add a ramp_time option that allows the user to specify a lead ramp time that must have passed before fio takes any performance numbers into account. Suggested by "Jenkins, Lee" Signed-off-by: Jens Axboe --- HOWTO | 5 +++++ fio.c | 16 +++++++++------- fio.h | 3 +++ io_u.c | 23 ++++++++++++++--------- options.c | 6 ++++++ time.c | 17 +++++++++++++++++ 6 files changed, 54 insertions(+), 16 deletions(-) diff --git a/HOWTO b/HOWTO index 7a65aa15..dd2f84a8 100644 --- a/HOWTO +++ b/HOWTO @@ -574,6 +574,11 @@ time_based If set, fio will run for the duration of the runtime written. It will simply loop over the same workload as many times as the runtime allows. +ramp_time If set, fio will run the specified workload for this amount + of time before logging any performance numbers. Useful for + letting performance settle before logging results, thus + minimizing the runtime required for stable results. + invalidate=bool Invalidate the buffer/page cache parts for this file prior to starting io. Defaults to true. diff --git a/fio.c b/fio.c index ee752e12..2a09fbe2 100644 --- a/fio.c +++ b/fio.c @@ -619,15 +619,17 @@ sync_done: * of completions except the very first one which may look * a little bursty */ - usec = utime_since(&s, &comp_time); + if (ramp_time_over(td)) { + usec = utime_since(&s, &comp_time); - rate_throttle(td, usec, bytes_done); + rate_throttle(td, usec, bytes_done); - if (check_min_rate(td, &comp_time)) { - if (exitall_on_terminate) - terminate_threads(td->groupid); - td_verror(td, EIO, "check_min_rate"); - break; + if (check_min_rate(td, &comp_time)) { + if (exitall_on_terminate) + terminate_threads(td->groupid); + td_verror(td, EIO, "check_min_rate"); + break; + } } if (td->o.thinktime) { diff --git a/fio.h b/fio.h index 22aaf345..a0c1109a 100644 --- a/fio.h +++ b/fio.h @@ -473,6 +473,7 @@ struct thread_options { unsigned int fsync_blocks; unsigned int start_delay; unsigned long long timeout; + unsigned long long ramp_time; unsigned int overwrite; unsigned int bw_avg_time; unsigned int loops; @@ -609,6 +610,7 @@ struct thread_data { struct timeval rw_end[2]; struct timeval last_issue; unsigned int rw_end_set[2]; + unsigned int ramp_time_over; /* * read/write mixed workload state @@ -817,6 +819,7 @@ extern void rate_throttle(struct thread_data *, unsigned long, unsigned int); extern void fill_start_time(struct timeval *); extern void fio_gettime(struct timeval *, void *); extern void set_genesis_time(void); +extern int ramp_time_over(struct thread_data *); /* * Init/option functions diff --git a/io_u.c b/io_u.c index 1dff88f1..17db16b1 100644 --- a/io_u.c +++ b/io_u.c @@ -903,24 +903,29 @@ static void io_completed(struct thread_data *td, struct io_u *io_u, if (!io_u->error) { unsigned int bytes = io_u->buflen - io_u->resid; const enum fio_ddir idx = io_u->ddir; - int ret; + int ret, ramp_done; - td->io_blocks[idx]++; - td->io_bytes[idx] += bytes; - td->this_io_bytes[idx] += bytes; + ramp_done = ramp_time_over(td); - usec = utime_since(&io_u->issue_time, &icd->time); + if (ramp_done) { + td->io_blocks[idx]++; + td->io_bytes[idx] += bytes; + td->this_io_bytes[idx] += bytes; - add_clat_sample(td, idx, usec); - add_bw_sample(td, idx, &icd->time); - io_u_mark_latency(td, usec); + usec = utime_since(&io_u->issue_time, &icd->time); + + add_clat_sample(td, idx, usec); + add_bw_sample(td, idx, &icd->time); + io_u_mark_latency(td, usec); + } if (td_write(td) && idx == DDIR_WRITE && td->o.do_verify && td->o.verify != VERIFY_NONE) log_io_piece(td, io_u); - icd->bytes_done[idx] += bytes; + if (ramp_done) + icd->bytes_done[idx] += bytes; if (io_u->end_io) { ret = io_u->end_io(td, io_u); diff --git a/options.c b/options.c index 0608e7b2..8723adff 100644 --- a/options.c +++ b/options.c @@ -831,6 +831,12 @@ static struct fio_option options[] = { .off1 = td_var_offset(time_based), .help = "Keep running until runtime/timeout is met", }, + { + .name = "ramp_time", + .type = FIO_OPT_STR_VAL_TIME, + .off1 = td_var_offset(ramp_time), + .help = "Ramp up time before measuring performance", + }, { .name = "mem", .alias = "iomem", diff --git a/time.c b/time.c index 505058f5..4f1c13a0 100644 --- a/time.c +++ b/time.c @@ -164,6 +164,23 @@ unsigned long mtime_since_genesis(void) return mtime_since_now(&genesis); } +int ramp_time_over(struct thread_data *td) +{ + struct timeval tv; + + if (!td->o.ramp_time || td->ramp_time_over) + return 1; + + fio_gettime(&tv, NULL); + if (mtime_since(&td->epoch, &tv) >= td->o.ramp_time * 1000) { + td->ramp_time_over = 1; + memcpy(&td->start, &tv, sizeof(tv)); + return 1; + } + + return 0; +} + static void fio_init time_init(void) { int i; -- 2.25.1