Add support for mixing a random IO workload a bit
authorJens Axboe <jens.axboe@oracle.com>
Thu, 22 Mar 2007 17:56:45 +0000 (18:56 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Thu, 22 Mar 2007 17:56:45 +0000 (18:56 +0100)
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 <jens.axboe@oracle.com>
HOWTO
fio.h
io_u.c
options.c

diff --git a/HOWTO b/HOWTO
index 76613714a14a063b4adc3133ee954f2b966748aa..051a4554a95ff8a1229d3154a1c6bd31f701c9c6 100644 (file)
--- 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 e33349088cebacb5869b4e4649cebea45f60b220..c34c00c064126934eec67ae1a543097cc158ce36 100644 (file)
--- 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 2b18e9f8a9a606c349304d843156f2b9a26025d0..45f37570b82b4d5e99eccf555cdac392f99a5815 100644 (file)
--- 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;
index e13b2b241342092b0d60b5c7b499fed4e85a0582..41ecd7fdd0d7818736c609a3108d6268e9c8f3e9 100644 (file)
--- 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",