From 8a069eb9a4b34e48ea41ac0e270cd2ccbd6fe3e8 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 30 Nov 2020 16:17:33 +0100 Subject: [PATCH] MINOR: debug: add a trivial PRNG for scheduler stress-tests Commit a5a447984 ("MINOR: debug: add "debug dev sched" to stress the scheduler.") doesn't scale with threads because ha_random64() takes care of being totally thread-safe for use with UUIDs. We don't need this for the stress-testing functions, let's just implement a xorshift PRNG instead. On 8 threads the performance jumped from 230k ctx/s with 96% spent in ha_random64() to 14M ctx/s. --- src/debug.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/debug.c b/src/debug.c index aaba9ca786..f83a7c018c 100644 --- a/src/debug.c +++ b/src/debug.c @@ -42,6 +42,17 @@ volatile unsigned long threads_to_dump = 0; unsigned int debug_commands_issued = 0; +/* Xorshift RNGs from http://www.jstatsoft.org/v08/i14/paper */ +static THREAD_LOCAL unsigned int y = 2463534242; +static unsigned int debug_prng() +{ + + y ^= y << 13; + y ^= y >> 17; + y ^= y << 5; + return y; +} + /* Dumps to the buffer some known information for the desired thread, and * optionally extra info for the current thread. The dump will be appended to * the buffer, so the caller is responsible for preliminary initializing it. @@ -684,7 +695,7 @@ static struct task *debug_task_handler(struct task *t, void *ctx, unsigned short t->expire = tick_add(now_ms, inter); /* half of the calls will wake up another entry */ - rnd = ha_random64(); + rnd = debug_prng(); if (rnd & 1) { rnd >>= 1; rnd %= tctx[0]; @@ -706,7 +717,7 @@ static struct task *debug_tasklet_handler(struct task *t, void *ctx, unsigned sh /* wake up two random entries */ for (i = 0; i < 2; i++) { - rnd = ha_random64() % tctx[0]; + rnd = debug_prng() % tctx[0]; rnd = tctx[rnd + 2]; if (rnd & 1) -- 2.39.5