From 5bfc35d7abe2582dc54127ca1d6e03792c9d62f5 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 7 Apr 2009 13:28:12 +0200 Subject: [PATCH] Reseed random generator for loop/time based runs Then we get repeatable 2nd/3rd/etc runs. This is important if the file layout was random, otherwise subsequent runs will get very different results. Signed-off-by: Jens Axboe --- fio.c | 5 +++++ fio.h | 3 +++ init.c | 42 +++++++++++++++++++++++------------------- io_u.c | 11 ----------- 4 files changed, 31 insertions(+), 30 deletions(-) diff --git a/fio.c b/fio.c index f699951d..ad2282d7 100644 --- a/fio.c +++ b/fio.c @@ -876,6 +876,11 @@ static void reset_io_counters(struct thread_data *td) */ if (td->o.time_based || td->o.loops) td->nr_done_files = 0; + + /* + * Set the same seed to get repeatable runs + */ + td_fill_rand_seeds(td); } void reset_all_stats(struct thread_data *td) diff --git a/fio.h b/fio.h index 4077a5be..ff0068ca 100644 --- a/fio.h +++ b/fio.h @@ -572,6 +572,8 @@ struct thread_data { char *sysfs_root; + unsigned long rand_seeds[6]; + os_random_state_t bsrange_state; os_random_state_t verify_state; @@ -854,6 +856,7 @@ extern int fio_show_option_help(const char *); extern void fio_options_dup_and_init(struct option *); extern void options_mem_dupe(struct thread_data *); extern void options_mem_free(struct thread_data *); +extern void td_fill_rand_seeds(struct thread_data *); #define FIO_GETOPT_JOB 0x89988998 #define FIO_NR_OPTIONS 128 diff --git a/init.c b/init.c index 80d098dd..8deedcc6 100644 --- a/init.c +++ b/init.c @@ -408,13 +408,32 @@ static int exists_and_not_file(const char *filename) return 1; } +void td_fill_rand_seeds(struct thread_data *td) +{ + os_random_seed(td->rand_seeds[0], &td->bsrange_state); + os_random_seed(td->rand_seeds[1], &td->verify_state); + os_random_seed(td->rand_seeds[2], &td->rwmix_state); + + if (td->o.file_service_type == FIO_FSERVICE_RANDOM) + os_random_seed(td->rand_seeds[3], &td->next_file_state); + + os_random_seed(td->rand_seeds[5], &td->file_size_state); + + if (!td_random(td)) + return; + + if (td->o.rand_repeatable) + td->rand_seeds[4] = FIO_RANDSEED * td->thread_number; + + os_random_seed(td->rand_seeds[4], &td->random_state); +} + /* * Initialize the various random states we need (random io, block size ranges, * read/write mix, etc). */ static int init_random_state(struct thread_data *td) { - unsigned long seeds[6]; int fd; fd = open("/dev/urandom", O_RDONLY); @@ -423,30 +442,15 @@ static int init_random_state(struct thread_data *td) return 1; } - if (read(fd, seeds, sizeof(seeds)) < (int) sizeof(seeds)) { + if (read(fd, td->rand_seeds, sizeof(td->rand_seeds)) < + (int) sizeof(td->rand_seeds)) { td_verror(td, EIO, "read"); close(fd); return 1; } close(fd); - - os_random_seed(seeds[0], &td->bsrange_state); - os_random_seed(seeds[1], &td->verify_state); - os_random_seed(seeds[2], &td->rwmix_state); - - if (td->o.file_service_type == FIO_FSERVICE_RANDOM) - os_random_seed(seeds[3], &td->next_file_state); - - os_random_seed(seeds[5], &td->file_size_state); - - if (!td_random(td)) - return 0; - - if (td->o.rand_repeatable) - seeds[4] = FIO_RANDSEED * td->thread_number; - - os_random_seed(seeds[4], &td->random_state); + td_fill_rand_seeds(td); return 0; } diff --git a/io_u.c b/io_u.c index 476658ed..71089390 100644 --- a/io_u.c +++ b/io_u.c @@ -748,23 +748,12 @@ static int set_io_u_file(struct thread_data *td, struct io_u *io_u) if (!f) return 1; -set_file: io_u->file = f; get_file(f); if (!fill_io_u(td, io_u)) break; - /* - * optimization to prevent close/open of the same file. This - * way we preserve queueing etc. - */ - if (td->o.nr_files == 1 && td->o.time_based) { - put_file_log(td, f); - fio_file_reset(f); - goto set_file; - } - put_file_log(td, f); td_io_close_file(td, f); io_u->file = NULL; -- 2.25.1