Simplify and optimize __fill_random_buf
authorGeorg Sauthoff <mail@gms.tf>
Thu, 30 Jun 2022 21:30:46 +0000 (23:30 +0200)
committerGeorg Sauthoff <mail@gms.tf>
Fri, 1 Jul 2022 20:15:35 +0000 (22:15 +0200)
This reduces the number of source lines and the code size.

For example, when compiling with GCC 12.1 (-O3 -march=skylake), the
resulting assembly shrinks from 33 to 27 instructions and the number of
jump instructions is reduced from 4 to 3.

NB: GCC is able to eliminate the memcpy() call.

NB: Even if a compiler doesn't eliminate the memcpy() call, it's very
unlikely to ever get called since the buffer sizes are expected to be
powers of two (>= 8), usually.

Signed-off-by: Georg Sauthoff <mail@gms.tf>
lib/rand.c

index 6e893e80ba00a4939116cb59099e881300aaed3e..2243c2b4342caed6e1983f52bd0c32ff9c024df4 100644 (file)
@@ -97,29 +97,18 @@ void init_rand_seed(struct frand_state *state, uint64_t seed, bool use64)
 
 void __fill_random_buf(void *buf, unsigned int len, uint64_t seed)
 {
-       void *ptr = buf;
+       uint64_t *b = buf;
+       uint64_t *e = b  + len / sizeof(*b);
+       unsigned int rest = len % sizeof(*b);
 
-       while (len) {
-               int this_len;
-
-               if (len >= sizeof(int64_t)) {
-                       *((int64_t *) ptr) = seed;
-                       this_len = sizeof(int64_t);
-               } else if (len >= sizeof(int32_t)) {
-                       *((int32_t *) ptr) = seed;
-                       this_len = sizeof(int32_t);
-               } else if (len >= sizeof(int16_t)) {
-                       *((int16_t *) ptr) = seed;
-                       this_len = sizeof(int16_t);
-               } else {
-                       *((int8_t *) ptr) = seed;
-                       this_len = sizeof(int8_t);
-               }
-               ptr += this_len;
-               len -= this_len;
+       for (; b != e; ++b) {
+               *b = seed;
                seed *= GOLDEN_RATIO_PRIME;
                seed >>= 3;
        }
+
+       if (fio_unlikely(rest))
+               __builtin_memcpy(e, &seed, rest);
 }
 
 uint64_t fill_random_buf(struct frand_state *fs, void *buf,