The following changes since commit fdba6ac393728b3f743013a6517a987fda79bd1a: Remove default setting of clocksource (2010-03-24 13:44:34 +0100) are available in the git repository at: git://git.kernel.dk/fio.git master Jens Axboe (8): Fix typo in bandwidth log command line option Keep the global command line bw/lat logs separate from per job logs First step at speeding up io_u rand refill Merge branch 'master' of ssh://brick.kernel.dk/data/git/fio Remember to prime the random generator "Expand" random number from 32-bit to 64-bit when necessary Add documentation for the random number generator Only use true random generator for initial seed Makefile | 2 + Makefile.FreeBSD | 2 + Makefile.mac | 2 + Makefile.solaris | 2 + fio.c | 2 + init.c | 5 +--- io_u.c | 10 ++++++++- lib/rand.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/rand.h | 23 +++++++++++++++++++++ 9 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 lib/rand.c create mode 100644 lib/rand.h --- Diff of recent changes: diff --git a/Makefile b/Makefile index 12042f4..837f421 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,8 @@ OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \ rbtree.o diskutil.o fifo.o blktrace.o smalloc.o filehash.o helpers.o \ cgroup.o profile.o debug.o +OBJS += lib/rand.o + OBJS += crc/crc7.o OBJS += crc/crc16.o OBJS += crc/crc32.o diff --git a/Makefile.FreeBSD b/Makefile.FreeBSD index deae03d..3c59a99 100644 --- a/Makefile.FreeBSD +++ b/Makefile.FreeBSD @@ -8,6 +8,8 @@ OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \ eta.o verify.o memory.o io_u.o parse.o mutex.o options.o \ rbtree.o smalloc.o filehash.o helpers.o profile.o debug.o +OBJS += lib/rand.o + OBJS += crc/crc7.o OBJS += crc/crc16.o OBJS += crc/crc32.o diff --git a/Makefile.mac b/Makefile.mac index a726546..fe84297 100644 --- a/Makefile.mac +++ b/Makefile.mac @@ -8,6 +8,8 @@ OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \ eta.o verify.o memory.o io_u.o parse.o mutex.o options.o \ rbtree.o smalloc.o filehash.o helpers.o profile.o debug.o +OBJS += lib/rand.o + OBJS += crc/crc7.o OBJS += crc/crc16.o OBJS += crc/crc32.o diff --git a/Makefile.solaris b/Makefile.solaris index 0ec6d73..49a4ef9 100644 --- a/Makefile.solaris +++ b/Makefile.solaris @@ -7,6 +7,8 @@ OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \ rbtree.o fifo.o smalloc.o filehash.o lib/strsep.o helpers.o solaris.o \ profile.o debug.o +OBJS += lib/rand.o + OBJS += crc/crc7.o OBJS += crc/crc16.o OBJS += crc/crc32.o diff --git a/fio.c b/fio.c index dfda268..03dc6cc 100644 --- a/fio.c +++ b/fio.c @@ -41,6 +41,7 @@ #include "diskutil.h" #include "cgroup.h" #include "profile.h" +#include "lib/rand.h" unsigned long page_mask; unsigned long page_size; @@ -1636,6 +1637,7 @@ int main(int argc, char *argv[]) long ps; sinit(); + init_rand(&__fio_rand_state); /* * We need locale for number printing, if it isn't set then just diff --git a/init.c b/init.c index 4d0a906..69941b2 100644 --- a/init.c +++ b/init.c @@ -881,9 +881,6 @@ static int fill_def_thread(void) fio_fill_default_options(&def_thread); def_thread.o.timeout = def_timeout; - def_thread.o.write_bw_log = write_bw_log; - def_thread.o.write_lat_log = write_lat_log; - return 0; } @@ -1076,7 +1073,7 @@ static int parse_cmd_line(int argc, char *argv[]) case 'l': write_lat_log = 1; break; - case 'w': + case 'b': write_bw_log = 1; break; case 'o': diff --git a/io_u.c b/io_u.c index afc90de..23037f1 100644 --- a/io_u.c +++ b/io_u.c @@ -8,6 +8,7 @@ #include "fio.h" #include "hash.h" #include "verify.h" +#include "lib/rand.h" struct io_completion_data { int nr; /* input */ @@ -1216,9 +1217,16 @@ void io_u_fill_buffer(struct thread_data *td, struct io_u *io_u, long *ptr = io_u->buf; if (!td->o.zero_buffers) { + unsigned long r = __rand(&__fio_rand_state); + + if (sizeof(int) != sizeof(*ptr)) + r *= (unsigned long) __rand(&__fio_rand_state); + while ((void *) ptr - io_u->buf < max_bs) { - *ptr = rand() * GOLDEN_RATIO_PRIME; + *ptr = r; ptr++; + r *= GOLDEN_RATIO_PRIME; + r >>= 3; } } else memset(ptr, 0, max_bs); diff --git a/lib/rand.c b/lib/rand.c new file mode 100644 index 0000000..cecc4c2 --- /dev/null +++ b/lib/rand.c @@ -0,0 +1,59 @@ +/* + This is a maximally equidistributed combined Tausworthe generator + based on code from GNU Scientific Library 1.5 (30 Jun 2004) + + x_n = (s1_n ^ s2_n ^ s3_n) + + s1_{n+1} = (((s1_n & 4294967294) <<12) ^ (((s1_n <<13) ^ s1_n) >>19)) + s2_{n+1} = (((s2_n & 4294967288) << 4) ^ (((s2_n << 2) ^ s2_n) >>25)) + s3_{n+1} = (((s3_n & 4294967280) <<17) ^ (((s3_n << 3) ^ s3_n) >>11)) + + The period of this generator is about 2^88. + + From: P. L'Ecuyer, "Maximally Equidistributed Combined Tausworthe + Generators", Mathematics of Computation, 65, 213 (1996), 203--213. + + This is available on the net from L'Ecuyer's home page, + + http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps + ftp://ftp.iro.umontreal.ca/pub/simulation/lecuyer/papers/tausme.ps + + There is an erratum in the paper "Tables of Maximally + Equidistributed Combined LFSR Generators", Mathematics of + Computation, 68, 225 (1999), 261--269: + http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps + + ... the k_j most significant bits of z_j must be non- + zero, for each j. (Note: this restriction also applies to the + computer code given in [4], but was mistakenly not mentioned in + that paper.) + + This affects the seeding procedure by imposing the requirement + s1 > 1, s2 > 7, s3 > 15. + +*/ + +#include "rand.h" + +struct frand_state __fio_rand_state; + +static inline int __seed(unsigned int x, unsigned int m) +{ + return (x < m) ? x + m : x; +} + +void init_rand(struct frand_state *state) +{ +#define LCG(x) ((x) * 69069) /* super-duper LCG */ + + state->s1 = __seed(LCG((2^31) + (2^17) + (2^7)), 1); + state->s2 = __seed(LCG(state->s1), 7); + state->s3 = __seed(LCG(state->s2), 15); + + __rand(state); + __rand(state); + __rand(state); + __rand(state); + __rand(state); + __rand(state); +} diff --git a/lib/rand.h b/lib/rand.h new file mode 100644 index 0000000..363e7b6 --- /dev/null +++ b/lib/rand.h @@ -0,0 +1,23 @@ +#ifndef FIO_RAND_H +#define FIO_RAND_H + +struct frand_state { + unsigned int s1, s2, s3; +}; + +extern struct frand_state __fio_rand_state; + +static inline unsigned int __rand(struct frand_state *state) +{ +#define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b) + + state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12); + state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4); + state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17); + + return (state->s1 ^ state->s2 ^ state->s3); +} + +extern void init_rand(struct frand_state *); + +#endif -- To unsubscribe from this list: send the line "unsubscribe fio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html