First step at speeding up io_u rand refill
authorJens Axboe <jens.axboe@oracle.com>
Thu, 25 Mar 2010 22:03:18 +0000 (23:03 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Thu, 25 Mar 2010 22:03:18 +0000 (23:03 +0100)
Makes it 3x faster here.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Makefile
Makefile.FreeBSD
Makefile.mac
Makefile.solaris
io_u.c
lib/rand.c [new file with mode: 0644]
lib/rand.h [new file with mode: 0644]

index 12042f4a92683a38cdf0cd62cbba27e7a198ba6f..837f42119da8a1aafc4bac331b98385934322230 100644 (file)
--- 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
index deae03d8e55ec5d8a7d4bdb1ce106e9de413403c..3c59a994284c6c228ee96900f945b9233fb646ca 100644 (file)
@@ -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
index a726546bb4a0139c3341582216c68f41b6b5854f..fe84297fdea1c26a3b3352a173e72556ddd837e0 100644 (file)
@@ -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
index 0ec6d730b8e6c58b2040aba26f26243b742108fc..49a4ef92618c77f09796f38e989e5d97b0d4acb2 100644 (file)
@@ -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/io_u.c b/io_u.c
index afc90de001f720d266d0ad612cb8c2d1873958f9..4d3116b7fd4fc0901f4419e8690270c2c18a2d43 100644 (file)
--- 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 */
@@ -1217,7 +1218,7 @@ void io_u_fill_buffer(struct thread_data *td, struct io_u *io_u,
 
        if (!td->o.zero_buffers) {
                while ((void *) ptr - io_u->buf < max_bs) {
-                       *ptr = rand() * GOLDEN_RATIO_PRIME;
+                       *ptr = __rand(&__fio_rand_state);
                        ptr++;
                }
        } else
diff --git a/lib/rand.c b/lib/rand.c
new file mode 100644 (file)
index 0000000..b8d8f78
--- /dev/null
@@ -0,0 +1,24 @@
+#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 (file)
index 0000000..363e7b6
--- /dev/null
@@ -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