All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jens Axboe <axboe@kernel.dk>
To: John Williams <jwilliams4200@gmail.com>
Cc: Brian Carey <brian@careydrive.com>, fio@vger.kernel.org
Subject: Re: Random IO pattern ratios
Date: Fri, 26 Apr 2013 08:47:36 -0600	[thread overview]
Message-ID: <20130426144736.GQ9563@kernel.dk> (raw)
In-Reply-To: <20130426134216.GO9563@kernel.dk>

On Fri, Apr 26 2013, Jens Axboe wrote:
> On Thu, Apr 25 2013, John Williams wrote:
> > Are there any plans to add %random / %sequential capability to fio?
> > 
> > That is the only feature IOMeter has that I miss in fio.
> 
> Sure, that'd be pretty easy to add. Let me take a look this morning.

Done. Did a few test runs to check it.

percentage_random=50
Random: 16313 (50.036808), Seq: 16289 (49.963192)

percentage_random=10
Random: 3239 (9.942292), Seq: 29339 (90.057708)

percentage_random=72
Random: 23467 (71.993496), Seq: 9129 (28.006504)

percentage_random=100
Random: 32596 (99.990797), Seq: 3 (0.009203)

percentage_random=0
Random: 1 (0.003066), Seq: 32613 (99.996934)

Note that the first IO is always counted as random, which is why the =0
test says only 99.996% sequential. In fact it is fully sequential.


diff --git a/cconv.c b/cconv.c
index 57c76e3..c2b2793 100644
--- a/cconv.c
+++ b/cconv.c
@@ -125,6 +125,8 @@ void convert_thread_options_to_cpu(struct thread_options *o,
 	o->zipf_theta.u.f = fio_uint64_to_double(le64_to_cpu(top->zipf_theta.u.i));
 	o->pareto_h.u.f = fio_uint64_to_double(le64_to_cpu(top->pareto_h.u.i));
 	o->random_generator = le32_to_cpu(top->random_generator);
+	o->perc_rand = le32_to_cpu(top->perc_rand);
+	o->perc_seq = le32_to_cpu(top->perc_seq);
 	o->hugepage_size = le32_to_cpu(top->hugepage_size);
 	o->rw_min_bs = le32_to_cpu(top->rw_min_bs);
 	o->thinktime = le32_to_cpu(top->thinktime);
@@ -283,6 +285,8 @@ void convert_thread_options_to_net(struct thread_options_pack *top,
 	top->zipf_theta.u.i = __cpu_to_le64(fio_double_to_uint64(o->zipf_theta.u.f));
 	top->pareto_h.u.i = __cpu_to_le64(fio_double_to_uint64(o->pareto_h.u.f));
 	top->random_generator = cpu_to_le32(o->random_generator);
+	top->perc_rand = cpu_to_le32(o->perc_rand);
+	top->perc_seq = cpu_to_le32(o->perc_seq);
 	top->hugepage_size = cpu_to_le32(o->hugepage_size);
 	top->rw_min_bs = cpu_to_le32(o->rw_min_bs);
 	top->thinktime = cpu_to_le32(o->thinktime);
diff --git a/fio.h b/fio.h
index 5438b76..965d7d9 100644
--- a/fio.h
+++ b/fio.h
@@ -81,6 +81,7 @@ enum {
 	FIO_RAND_FILE_SIZE_OFF,
 	FIO_RAND_TRIM_OFF,
 	FIO_RAND_BUF_OFF,
+	FIO_RAND_SEQ_RAND_OFF,
 	FIO_RAND_NR_OFFS,
 };
 
@@ -256,6 +257,14 @@ struct thread_data {
 	unsigned int ddir_seq_nr;
 
 	/*
+	 * rand/seq mixed workload state
+	 */
+	union {
+		os_random_state_t seq_rand_state;
+		struct frand_state __seq_rand_state;
+	};
+
+	/*
 	 * IO history logs for verification. We use a tree for sorting,
 	 * if we are overwriting. Otherwise just use a fifo.
 	 */
diff --git a/init.c b/init.c
index aba7671..7246bd8 100644
--- a/init.c
+++ b/init.c
@@ -701,6 +701,7 @@ static void td_fill_rand_seeds_os(struct thread_data *td)
 		td->rand_seeds[FIO_RAND_BLOCK_OFF] = FIO_RANDSEED * td->thread_number;
 
 	os_random_seed(td->rand_seeds[FIO_RAND_BLOCK_OFF], &td->random_state);
+	os_random_seed(td->rand_seeds[FIO_RAND_SEQ_RAND_OFF], &td->seq_rand_state);
 }
 
 static void td_fill_rand_seeds_internal(struct thread_data *td)
@@ -722,6 +723,7 @@ static void td_fill_rand_seeds_internal(struct thread_data *td)
 		td->rand_seeds[FIO_RAND_BLOCK_OFF] = FIO_RANDSEED * td->thread_number;
 
 	init_rand_seed(&td->__random_state, td->rand_seeds[FIO_RAND_BLOCK_OFF]);
+	init_rand_seed(&td->__seq_rand_state, td->rand_seeds[FIO_RAND_SEQ_RAND_OFF]);
 }
 
 void td_fill_rand_seeds(struct thread_data *td)
diff --git a/io_u.c b/io_u.c
index 19ef7b9..d03049e 100644
--- a/io_u.c
+++ b/io_u.c
@@ -191,6 +191,25 @@ static inline int should_sort_io(struct thread_data *td)
 	return 1;
 }
 
+static int should_do_random(struct thread_data *td)
+{
+	unsigned int v;
+	unsigned long r;
+
+	if (td->o.perc_rand == 100)
+		return 1;
+
+	if (td->o.use_os_rand) {
+		r = os_random_long(&td->seq_rand_state);
+		v = 1 + (int) (100.0 * (r / (OS_RAND_MAX + 1.0)));
+	} else {
+		r = __rand(&td->__seq_rand_state);
+		v = 1 + (int) (100.0 * (r / (FRAND_MAX + 1.0)));
+	}
+
+	return v <= td->o.perc_rand;
+}
+
 static int get_next_rand_offset(struct thread_data *td, struct fio_file *f,
 				enum fio_ddir ddir, uint64_t *b)
 {
@@ -285,9 +304,16 @@ static int get_next_block(struct thread_data *td, struct io_u *io_u,
 	b = offset = -1ULL;
 
 	if (rw_seq) {
-		if (td_random(td))
-			ret = get_next_rand_block(td, f, ddir, &b);
-		else
+		if (td_random(td)) {
+			if (should_do_random(td))
+				ret = get_next_rand_block(td, f, ddir, &b);
+			else {
+				io_u->flags |= IO_U_F_BUSY_OK;
+				ret = get_next_seq_offset(td, f, ddir, &offset);
+				if (ret)
+					ret = get_next_rand_block(td, f, ddir, &b);
+			}
+		} else
 			ret = get_next_seq_offset(td, f, ddir, &offset);
 	} else {
 		io_u->flags |= IO_U_F_BUSY_OK;
diff --git a/options.c b/options.c
index 1219803..97c5b6f 100644
--- a/options.c
+++ b/options.c
@@ -376,6 +376,25 @@ static int str_rwmix_write_cb(void *data, unsigned long long *val)
 	return 0;
 }
 
+static int str_perc_rand_cb(void *data, unsigned long long *val)
+{
+	struct thread_data *td = data;
+
+	td->o.perc_rand = *val;
+	td->o.perc_seq = 100 - *val;
+	return 0;
+}
+
+static int str_perc_seq_cb(void *data, unsigned long long *val)
+{
+	struct thread_data *td = data;
+
+	td->o.perc_seq = *val;
+	td->o.perc_rand = 100 - *val;
+	return 0;
+}
+
+
 static int str_exitall_cb(void)
 {
 	exitall_on_terminate = 1;
@@ -1643,6 +1662,32 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
 		.group	= FIO_OPT_G_RANDOM,
 	},
 	{
+		.name	= "percentage_random",
+		.lname	= "Percentage Random",
+		.type	= FIO_OPT_INT,
+		.cb	= str_perc_rand_cb,
+		.maxval	= 100,
+		.help	= "Percentage of seq/random mix that should be random",
+		.def	= "100",
+		.interval = 5,
+		.inverse = "percentage_sequential",
+		.category = FIO_OPT_C_IO,
+		.group	= FIO_OPT_G_RANDOM,
+	},
+	{
+		.name	= "percentage_sequential",
+		.lname	= "Percentage Sequential",
+		.type	= FIO_OPT_INT,
+		.cb	= str_perc_seq_cb,
+		.maxval	= 100,
+		.help	= "Percentage of seq/random mix that should be sequential",
+		.def	= "0",
+		.interval = 5,
+		.inverse = "percentage_random",
+		.category = FIO_OPT_C_IO,
+		.group	= FIO_OPT_G_RANDOM,
+	},
+	{
 		.name	= "nrfiles",
 		.lname	= "Number of files",
 		.alias	= "nr_files",
diff --git a/thread_options.h b/thread_options.h
index f25988a..138d026 100644
--- a/thread_options.h
+++ b/thread_options.h
@@ -113,6 +113,9 @@ struct thread_options {
 
 	unsigned int random_generator;
 
+	unsigned int perc_rand;
+	unsigned int perc_seq;
+
 	unsigned int hugepage_size;
 	unsigned int rw_min_bs;
 	unsigned int thinktime;
@@ -322,6 +325,9 @@ struct thread_options_pack {
 
 	uint32_t random_generator;
 
+	uint32_t perc_rand;
+	uint32_t perc_seq;
+
 	uint32_t hugepage_size;
 	uint32_t rw_min_bs;
 	uint32_t thinktime;

-- 
Jens Axboe


  reply	other threads:[~2013-04-26 14:47 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-25 14:47 Random IO pattern ratios Brian Carey
2013-04-26  3:44 ` Jens Axboe
2013-04-26  4:32   ` John Williams
2013-04-26 11:49     ` Brian Carey
2013-04-26 11:53     ` Brian Carey
2013-04-26 13:42     ` Jens Axboe
2013-04-26 14:47       ` Jens Axboe [this message]
2013-04-26 14:57         ` Jens Axboe
2013-04-26 17:52         ` John Williams

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130426144736.GQ9563@kernel.dk \
    --to=axboe@kernel.dk \
    --cc=brian@careydrive.com \
    --cc=fio@vger.kernel.org \
    --cc=jwilliams4200@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.