summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGeorg Sauthoff <mail@gms.tf>2022-06-30 23:30:46 +0200
committerGeorg Sauthoff <mail@gms.tf>2022-07-01 22:15:35 +0200
commit5366025a15bd794052d3e74be450c5a70e12bf0c (patch)
tree653ff24340f380fa9ce310b93568abe24332bff0 /lib
parent660879102e32a0ed3d3225afaebcc0d46625a4a6 (diff)
downloadfio-5366025a15bd794052d3e74be450c5a70e12bf0c.tar.gz
fio-5366025a15bd794052d3e74be450c5a70e12bf0c.tar.bz2
Simplify and optimize __fill_random_buf
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>
Diffstat (limited to 'lib')
-rw-r--r--lib/rand.c27
1 files changed, 8 insertions, 19 deletions
diff --git a/lib/rand.c b/lib/rand.c
index 6e893e80..2243c2b4 100644
--- a/lib/rand.c
+++ b/lib/rand.c
@@ -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,