Add pareto distribution randomizer
authorJens Axboe <axboe@kernel.dk>
Tue, 6 Nov 2012 12:50:32 +0000 (13:50 +0100)
committerJens Axboe <axboe@kernel.dk>
Tue, 6 Nov 2012 12:50:32 +0000 (13:50 +0100)
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fio.h
init.c
io_u.c
lib/zipf.c
lib/zipf.h
options.c

diff --git a/fio.h b/fio.h
index 15ab308488c23b1f6608e1f682d70a4696adc506..7eb0abba0fa5572222e08a3caa7db63198bc0a98 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -180,6 +180,7 @@ struct thread_options {
 
        unsigned int random_distribution;
        double zipf_theta;
+       double pareto_h;
 
        unsigned int hugepage_size;
        unsigned int rw_min_bs;
@@ -827,6 +828,7 @@ enum {
 enum {
        FIO_RAND_DIST_RANDOM    = 0,
        FIO_RAND_DIST_ZIPF,
+       FIO_RAND_DIST_PARETO,
 };
 
 #endif
diff --git a/init.c b/init.c
index 1cee0964d094c87d9d0bc24ad56da511cfbdd77f..bf4aa03041435a038bd6fd72b636cab10ddd4c9a 100644 (file)
--- a/init.c
+++ b/init.c
@@ -393,7 +393,11 @@ static void init_rand_distribution(struct thread_data *td)
        range_size = min(td->o.min_bs[DDIR_READ], td->o.min_bs[DDIR_WRITE]);
 
        nranges = (td->o.size + range_size - 1) / range_size;
-       zipf_init(&td->zipf, nranges, td->o.zipf_theta);
+
+       if (td->o.random_distribution == FIO_RAND_DIST_ZIPF)
+               zipf_init(&td->zipf, nranges, td->o.zipf_theta);
+       else
+               pareto_init(&td->zipf, nranges, td->o.pareto_h);
 }
 
 /*
diff --git a/io_u.c b/io_u.c
index 8f2ce302080c4ba8c1b54d5e8f41a7e408d5c902..688249bd8a727e7910d72388a829f7249b5ee059 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -234,13 +234,22 @@ ret:
        return 0;
 }
 
-static int __get_next_rand_offset_zipf(struct thread_data *td, struct fio_file *f,
-                                 enum fio_ddir ddir, unsigned long long *b)
+static int __get_next_rand_offset_zipf(struct thread_data *td,
+                                      struct fio_file *f, enum fio_ddir ddir,
+                                      unsigned long long *b)
 {
        *b = zipf_next(&td->zipf);
        return 0;
 }
 
+static int __get_next_rand_offset_pareto(struct thread_data *td,
+                                        struct fio_file *f, enum fio_ddir ddir,
+                                        unsigned long long *b)
+{
+       *b = pareto_next(&td->zipf);
+       return 0;
+}
+
 static int get_next_rand_offset(struct thread_data *td, struct fio_file *f,
                                enum fio_ddir ddir, unsigned long long *b)
 {
@@ -248,6 +257,8 @@ static int get_next_rand_offset(struct thread_data *td, struct fio_file *f,
                return __get_next_rand_offset(td, f, ddir, b);
        else if (td->o.random_distribution == FIO_RAND_DIST_ZIPF)
                return __get_next_rand_offset_zipf(td, f, ddir, b);
+       else if (td->o.random_distribution == FIO_RAND_DIST_PARETO)
+               return __get_next_rand_offset_pareto(td, f, ddir, b);
 
        log_err("fio: unknown random distribution: %d\n", td->o.random_distribution);
        return 1;
index 34f28772682dba677a7da5d6d18a23fec57e0ed0..28e8d77e5602d13b95e73e561ce4df418750d441 100644 (file)
@@ -126,3 +126,21 @@ unsigned long long zipf_next(struct zipf_state *zs)
 
        return val - 1;
 }
+
+void pareto_init(struct zipf_state *zs, unsigned long nranges, double h)
+{
+       memset(zs, 0, sizeof(*zs));
+
+       zs->nranges = nranges;
+       zs->pareto_pow = log(h) / log(1.0 - h);
+
+       init_rand(&zs->rand);
+}
+
+unsigned long long pareto_next(struct zipf_state *zs)
+{
+       double rand = (double) __rand(&zs->rand) / (double) FRAND_MAX;
+       unsigned long long n = zs->nranges - 1;
+
+       return n * pow(rand, zs->pareto_pow);
+}
index 6578ef1c008a88e26397e966fea691e53e83df4b..97a9b32fe6aeedc6b56b87d00545779b7f026d75 100644 (file)
@@ -8,10 +8,14 @@ struct zipf_state {
        double theta;
        double zeta2;
        double zetan;
+       double pareto_pow;
        struct frand_state rand;
 };
 
 void zipf_init(struct zipf_state *zs, unsigned long nranges, double theta);
 unsigned long long zipf_next(struct zipf_state *zs);
 
+void pareto_init(struct zipf_state *zs, unsigned long nranges, double h);
+unsigned long long pareto_next(struct zipf_state *zs);
+
 #endif
index 05a6a5081fa576810c9071506e634077ec27a401..ea1ffb13dd8bf95dd0f8c0bb1bbb0a8f257921c0 100644 (file)
--- a/options.c
+++ b/options.c
@@ -734,19 +734,25 @@ static int str_random_distribution_cb(void *data, const char *str)
        double val;
        char *nr;
 
-       if (td->o.random_distribution == FIO_RAND_DIST_RANDOM)
+       if (td->o.random_distribution == FIO_RAND_DIST_ZIPF)
+               val = 1.1;
+       else if (td->o.random_distribution == FIO_RAND_DIST_PARETO)
+               val = 0.2;
+       else
                return 0;
 
        nr = get_opt_postfix(str);
-       if (!nr)
-               val = 0.6;
-       else if (!str_to_float(nr, &val)) {
+       if (nr && !str_to_float(nr, &val)) {
                log_err("fio: random postfix parsing failed\n");
                free(nr);
                return 1;
        }
 
-       td->o.zipf_theta = val;
+       if (td->o.random_distribution == FIO_RAND_DIST_ZIPF)
+               td->o.zipf_theta = val;
+       else
+               td->o.pareto_h = val;
+
        free(nr);
        return 0;
 }
@@ -1511,6 +1517,10 @@ static struct fio_option options[FIO_MAX_OPTS] = {
                            .oval = FIO_RAND_DIST_ZIPF,
                            .help = "Zipf distribution",
                          },
+                         { .ival = "pareto",
+                           .oval = FIO_RAND_DIST_PARETO,
+                           .help = "Pareto distribution",
+                         },
                },
        },
        {