Add pareto distribution randomizer
Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/fio.h b/fio.h
index 15ab308..7eb0abb 100644
--- a/fio.h
+++ b/fio.h
@@ -180,6 +180,7 @@
unsigned int random_distribution;
double zipf_theta;
+ double pareto_h;
unsigned int hugepage_size;
unsigned int rw_min_bs;
@@ -827,6 +828,7 @@
enum {
FIO_RAND_DIST_RANDOM = 0,
FIO_RAND_DIST_ZIPF,
+ FIO_RAND_DIST_PARETO,
};
#endif
diff --git a/init.c b/init.c
index 1cee096..bf4aa03 100644
--- a/init.c
+++ b/init.c
@@ -393,7 +393,11 @@
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 8f2ce30..688249b 100644
--- a/io_u.c
+++ b/io_u.c
@@ -234,13 +234,22 @@
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 @@
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;
diff --git a/lib/zipf.c b/lib/zipf.c
index 34f2877..28e8d77 100644
--- a/lib/zipf.c
+++ b/lib/zipf.c
@@ -126,3 +126,21 @@
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);
+}
diff --git a/lib/zipf.h b/lib/zipf.h
index 6578ef1..97a9b32 100644
--- a/lib/zipf.h
+++ b/lib/zipf.h
@@ -8,10 +8,14 @@
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
diff --git a/options.c b/options.c
index 05a6a50..ea1ffb1 100644
--- a/options.c
+++ b/options.c
@@ -734,19 +734,25 @@
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 @@
.oval = FIO_RAND_DIST_ZIPF,
.help = "Zipf distribution",
},
+ { .ival = "pareto",
+ .oval = FIO_RAND_DIST_PARETO,
+ .help = "Pareto distribution",
+ },
},
},
{