summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSungup Moon <sungup.moon@samsung.com>2022-08-08 17:21:46 +0900
committerSungup Moon <sungup.moon@samsung.com>2022-08-10 23:34:12 +0900
commit7ff204c83595cd7d6b7b6a813d9fda97afd25198 (patch)
treea4341317fa5b2dac4c05cf0e360b1c16bfa7b605 /lib
parentde31fe9ab3dd6115cd0d5c77354f67f06595570d (diff)
downloadfio-7ff204c83595cd7d6b7b6a813d9fda97afd25198.tar.gz
fio-7ff204c83595cd7d6b7b6a813d9fda97afd25198.tar.bz2
lib/rand: Enhance __fill_random_buf using the multi random seed
The __fill_random_buf fills a buffer using the random 8byte integer to write. But, this mechanism is depend on the CPU performance and could not reach the max performance on the PCIe Gen5 devices. I have tested 128KB single worker sequential write on PCIe Gen5 NVMe, but it cannot reach write throughput 6.0GB/s. So, I have reviewed the __fill_random_buf and focused the multiplier dependency to generate the random number. So, I have changed __fill_random_buf using the multiple-random-seed to reduce the dependencies in the small data filling loop. I'll attach detail analysis result in the PR of this branch. Signed-off-by: Sungup Moon <sungup.moon@samsung.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/rand.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/lib/rand.c b/lib/rand.c
index 1e669116..1ce4a849 100644
--- a/lib/rand.c
+++ b/lib/rand.c
@@ -95,7 +95,7 @@ void init_rand_seed(struct frand_state *state, uint64_t seed, bool use64)
__init_rand64(&state->state64, seed);
}
-void __fill_random_buf(void *buf, unsigned int len, uint64_t seed)
+void __fill_random_buf_small(void *buf, unsigned int len, uint64_t seed)
{
uint64_t *b = buf;
uint64_t *e = b + len / sizeof(*b);
@@ -110,6 +110,41 @@ void __fill_random_buf(void *buf, unsigned int len, uint64_t seed)
__builtin_memcpy(e, &seed, rest);
}
+void __fill_random_buf(void *buf, unsigned int len, uint64_t seed)
+{
+#define MAX_SEED_BUCKETS 16
+ static uint64_t prime[MAX_SEED_BUCKETS] = {1, 2, 3, 5,
+ 7, 11, 13, 17,
+ 19, 23, 29, 31,
+ 37, 41, 43, 47};
+
+ uint64_t *b, *e, s[CONFIG_SEED_BUCKETS];
+ unsigned int rest;
+ int p;
+
+ /*
+ * Calculate the max index which is multiples of the seed buckets.
+ */
+ rest = (len / sizeof(*b) / CONFIG_SEED_BUCKETS) * CONFIG_SEED_BUCKETS;
+
+ b = buf;
+ e = b + rest;
+
+ rest = len - (rest * sizeof(*b));
+
+ for (p = 0; p < CONFIG_SEED_BUCKETS; p++)
+ s[p] = seed * prime[p];
+
+ for (; b != e; b += CONFIG_SEED_BUCKETS) {
+ for (p = 0; p < CONFIG_SEED_BUCKETS; ++p) {
+ b[p] = s[p];
+ s[p] = __hash_u64(s[p]);
+ }
+ }
+
+ __fill_random_buf_small(b, rest, s[0]);
+}
+
uint64_t fill_random_buf(struct frand_state *fs, void *buf,
unsigned int len)
{