Use 32-bit rand for parts that use rand_between()
authorJens Axboe <axboe@fb.com>
Thu, 10 Mar 2016 19:09:14 +0000 (12:09 -0700)
committerJens Axboe <axboe@fb.com>
Thu, 10 Mar 2016 19:09:14 +0000 (12:09 -0700)
We don't need a full 32-bit space for these, and the 32-bit generator
is faster.

Signed-off-by: Jens Axboe <axboe@fb.com>
init.c
io_u.c
lib/rand.c
lib/rand.h
t/gen-rand.c

diff --git a/init.c b/init.c
index 149029a52574a02c91e09d4887abbf685505345c..9052addc9c7ff2117e557ad74ca5f90096f5e139 100644 (file)
--- a/init.c
+++ b/init.c
@@ -919,11 +919,13 @@ static int exists_and_not_file(const char *filename)
        return 1;
 }
 
-static void td_fill_rand_seeds_internal(struct thread_data *td, int use64)
+static void td_fill_rand_seeds_internal(struct thread_data *td, bool use64)
 {
+       int i;
+
        init_rand_seed(&td->bsrange_state, td->rand_seeds[FIO_RAND_BS_OFF], use64);
        init_rand_seed(&td->verify_state, td->rand_seeds[FIO_RAND_VER_OFF], use64);
-       init_rand_seed(&td->rwmix_state, td->rand_seeds[FIO_RAND_MIX_OFF], use64);
+       init_rand_seed(&td->rwmix_state, td->rand_seeds[FIO_RAND_MIX_OFF], false);
 
        if (td->o.file_service_type == FIO_FSERVICE_RANDOM)
                init_rand_seed(&td->next_file_state, td->rand_seeds[FIO_RAND_FILE_OFF], use64);
@@ -932,6 +934,8 @@ static void td_fill_rand_seeds_internal(struct thread_data *td, int use64)
        init_rand_seed(&td->trim_state, td->rand_seeds[FIO_RAND_TRIM_OFF], use64);
        init_rand_seed(&td->delay_state, td->rand_seeds[FIO_RAND_START_DELAY], use64);
        init_rand_seed(&td->poisson_state, td->rand_seeds[FIO_RAND_POISSON_OFF], 0);
+       init_rand_seed(&td->dedupe_state, td->rand_seeds[FIO_DEDUPE_OFF], false);
+       init_rand_seed(&td->zone_state, td->rand_seeds[FIO_RAND_ZONE_OFF], false);
 
        if (!td_random(td))
                return;
@@ -940,14 +944,17 @@ static void td_fill_rand_seeds_internal(struct thread_data *td, int use64)
                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], use64);
-       init_rand_seed(&td->seq_rand_state[DDIR_READ], td->rand_seeds[FIO_RAND_SEQ_RAND_READ_OFF], use64);
-       init_rand_seed(&td->seq_rand_state[DDIR_WRITE], td->rand_seeds[FIO_RAND_SEQ_RAND_WRITE_OFF], use64);
-       init_rand_seed(&td->seq_rand_state[DDIR_TRIM], td->rand_seeds[FIO_RAND_SEQ_RAND_TRIM_OFF], use64);
+
+       for (i = 0; i < DDIR_RWDIR_CNT; i++) {
+               struct frand_state *s = &td->seq_rand_state[i];
+
+               init_rand_seed(s, td->rand_seeds[FIO_RAND_SEQ_RAND_READ_OFF], false);
+       }
 }
 
 void td_fill_rand_seeds(struct thread_data *td)
 {
-       int use64;
+       bool use64;
 
        if (td->o.allrand_repeatable) {
                unsigned int i;
@@ -966,9 +973,6 @@ void td_fill_rand_seeds(struct thread_data *td)
 
        init_rand_seed(&td->buf_state, td->rand_seeds[FIO_RAND_BUF_OFF], use64);
        frand_copy(&td->buf_state_prev, &td->buf_state);
-
-       init_rand_seed(&td->dedupe_state, td->rand_seeds[FIO_DEDUPE_OFF], use64);
-       init_rand_seed(&td->zone_state, td->rand_seeds[FIO_RAND_ZONE_OFF], use64);
 }
 
 /*
diff --git a/io_u.c b/io_u.c
index 3299f2907af47bb3e6d7b59d2c35aad004509df2..ea08c927f72e1b9d96e2ae05d5a1eb8fba122b9c 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -177,7 +177,7 @@ bail:
        /*
         * Generate a value, v, between 1 and 100, both inclusive
         */
-       v = rand_between(&td->zone_state, 1, 100);
+       v = rand32_between(&td->zone_state, 1, 100);
 
        zsi = &td->zone_state_index[ddir][v - 1];
        stotal = zsi->size_perc_prev;
@@ -279,7 +279,7 @@ static bool should_do_random(struct thread_data *td, enum fio_ddir ddir)
        if (td->o.perc_rand[ddir] == 100)
                return true;
 
-       v = rand_between(&td->seq_rand_state[ddir], 1, 100);
+       v = rand32_between(&td->seq_rand_state[ddir], 1, 100);
 
        return v <= td->o.perc_rand[ddir];
 }
@@ -601,7 +601,7 @@ static inline enum fio_ddir get_rand_ddir(struct thread_data *td)
 {
        unsigned int v;
 
-       v = rand_between(&td->rwmix_state, 1, 100);
+       v = rand32_between(&td->rwmix_state, 1, 100);
 
        if (v <= td->o.rwmix[DDIR_READ])
                return DDIR_READ;
@@ -1964,7 +1964,7 @@ static struct frand_state *get_buf_state(struct thread_data *td)
                return &td->buf_state;
        }
 
-       v = rand_between(&td->dedupe_state, 1, 100);
+       v = rand32_between(&td->dedupe_state, 1, 100);
 
        if (v <= td->o.dedupe_percentage)
                return &td->buf_state_prev;
index 9c3e0d6a39e181149ad04ac5c36f7220d115de95..12916cf00ddfd2b6d6ec31e82258300836cb3537 100644 (file)
@@ -46,7 +46,7 @@ static inline uint64_t __seed(uint64_t x, uint64_t m)
        return (x < m) ? x + m : x;
 }
 
-static void __init_rand32(struct taus88_state *state, unsigned int seed)
+void __init_rand32(struct taus88_state *state, unsigned int seed)
 {
        int cranks = 6;
 
@@ -60,7 +60,7 @@ static void __init_rand32(struct taus88_state *state, unsigned int seed)
                __rand32(state);
 }
 
-static void __init_rand64(struct taus258_state *state, uint64_t seed)
+void __init_rand64(struct taus258_state *state, uint64_t seed)
 {
        int cranks = 6;
 
index 24fac23cfec0856b409405e69a313dc7e873be33..bff4a35167cbbfc95dc9258c54b5bbec3f1400e4 100644 (file)
@@ -2,6 +2,7 @@
 #define FIO_RAND_H
 
 #include <inttypes.h>
+#include <assert.h>
 #include "types.h"
 #include "../arch/arch.h"
 
@@ -24,10 +25,6 @@ struct frand_state {
        };
 };
 
-struct frand64_state {
-       uint64_t s1, s2, s3, s4, s5;
-};
-
 static inline uint64_t rand_max(struct frand_state *state)
 {
        if (state->use64)
@@ -121,12 +118,14 @@ static inline double __rand_0_1(struct frand_state *state)
 /*
  * Generate a random value between 'start' and 'end', both inclusive
  */
-static inline int rand_between(struct frand_state *state, int start, int end)
+static inline int rand32_between(struct frand_state *state, int start, int end)
 {
-       uint64_t r;
+       uint32_t r;
+
+       assert(!state->use64);
 
-       r = __rand(state);
-       return start + (int) ((double)end * (r / (rand_max(state) + 1.0)));
+       r = __rand32(&state->state32);
+       return start + (int) ((double)end * (r / (FRAND32_MAX + 1.0)));
 }
 
 extern void init_rand(struct frand_state *, bool);
index ace814fa7dbcfe83a77d7163fa0ab7018d28249f..6c31f92598fc1686e05f905be24237b576b61b18 100644 (file)
@@ -40,7 +40,7 @@ int main(int argc, char *argv[])
        init_rand(&s, false);
 
        for (i = 0; i < nvalues; i++) {
-               int v = rand_between(&s, start, end);
+               int v = rand32_between(&s, start, end);
 
                buckets[v - start]++;
        }