From: Jens Axboe Date: Thu, 22 Mar 2007 17:56:45 +0000 (+0100) Subject: Add support for mixing a random IO workload a bit X-Git-Tag: fio-1.15~48 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=211097b2aa664b8c157692a1e2fe656ed4a3488c Add support for mixing a random IO workload a bit Now you can append a number to randread/randwrite (and others) to specify only getting a random offset for every X number of ios. Signed-off-by: Jens Axboe --- diff --git a/HOWTO b/HOWTO index 76613714..051a4554 100644 --- a/HOWTO +++ b/HOWTO @@ -228,7 +228,14 @@ rw=str Type of io pattern. Accepted values are: For the mixed io types, the default is to split them 50/50. For certain types of io the result may still be skewed a bit, - since the speed may be different. + since the speed may be different. It is possible to specify + a number of IO's to do before getting a new offset - this + is only useful for random IO, where fio would normally + generate a new random offset for every IO. If you append + eg 8 to randread, you would get a new random offset for + every 8 IO's. The result would be a seek for only every 8 + IO's, instead of for every IO. Use rw=randread:8 to specify + that. randrepeat=bool For random IO workloads, seed the generator in a predictable way so that results are repeatable across repetitions. diff --git a/fio.h b/fio.h index e3334908..c34c00c0 100644 --- a/fio.h +++ b/fio.h @@ -325,6 +325,7 @@ struct thread_options { char *opendir; char *ioengine; enum td_ddir td_ddir; + unsigned int ddir_nr; unsigned int iodepth; unsigned int iodepth_low; unsigned int iodepth_batch; @@ -503,6 +504,7 @@ struct thread_data { unsigned long long rwmix_bytes; struct timeval rwmix_switch; enum fio_ddir rwmix_ddir; + unsigned int ddir_nr; /* * IO historic logs diff --git a/io_u.c b/io_u.c index 2b18e9f8..45f37570 100644 --- a/io_u.c +++ b/io_u.c @@ -52,7 +52,7 @@ static void mark_random_map(struct thread_data *td, struct io_u *io_u) while (blocks < nr_blocks) { unsigned int idx, bit; - if (!random_map_free(td, f, block)) + if (!td->o.ddir_nr && !random_map_free(td, f, block)) break; idx = RAND_MAP_IDX(td, f, block); @@ -109,6 +109,16 @@ static int get_next_offset(struct thread_data *td, struct io_u *io_u) unsigned long long max_blocks = f->file_size / td->o.min_bs[ddir]; int loops = 5; + if (td->o.ddir_nr) { + if (!td->ddir_nr) + td->ddir_nr = td->o.ddir_nr; + else if (--td->ddir_nr) { + b = f->last_pos / td->o.min_bs[ddir]; + goto out; + } else + td->ddir_nr = td->o.ddir_nr; + } + do { r = os_random_long(&td->random_state); if (!max_blocks) @@ -130,6 +140,7 @@ static int get_next_offset(struct thread_data *td, struct io_u *io_u) } else b = f->last_pos / td->o.min_bs[ddir]; +out: io_u->offset = (b * td->o.min_bs[ddir]) + f->file_offset; if (io_u->offset >= f->real_file_size) return 1; diff --git a/options.c b/options.c index e13b2b24..41ecd7fd 100644 --- a/options.c +++ b/options.c @@ -27,6 +27,20 @@ static char *get_opt_postfix(const char *str) return strdup(p); } +static int str_rw_cb(void *data, const char *str) +{ + struct thread_data *td = data; + char *nr = get_opt_postfix(str); + + td->o.ddir_nr = 0; + if (nr) + td->o.ddir_nr = atoi(nr); + + printf("ddir_nr=%d\n", td->o.ddir_nr); + + return 0; +} + static int str_mem_cb(void *data, const char *mem) { struct thread_data *td = data; @@ -203,6 +217,7 @@ static struct fio_option options[] = { .name = "rw", .alias = "readwrite", .type = FIO_OPT_STR, + .cb = str_rw_cb, .off1 = td_var_offset(td_ddir), .help = "IO direction", .def = "read",