Update xorshift PRNG
Release / release (push) Successful in 4s

This commit is contained in:
2026-09-06 13:31:37 +01:00
parent 07e0034783
commit c83f9333de
3 changed files with 39 additions and 24 deletions
+5
View File
@@ -15,6 +15,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `wpSip24Hasher128IO`, `wpSip48Hasher128IO`, `wpSip24Hasher64IO` and `wpSip48Hasher64IO` to setup the siphash IO structs for the different variants - `wpSip24Hasher128IO`, `wpSip48Hasher128IO`, `wpSip24Hasher64IO` and `wpSip48Hasher64IO` to setup the siphash IO structs for the different variants
- `wpSipHasher128` and `wpSipHasher64` implementation for the 128 and 64 variants of siphash - `wpSipHasher128` and `wpSipHasher64` implementation for the 128 and 64 variants of siphash
- Add `wpU8Const`, `wpU16Const`, `wpU32Const`, `wpU64Const`, `wpI8Const`, `wpI16Const`, `wpI32Const`, and `wpI64Const` - Add `wpU8Const`, `wpU16Const`, `wpU32Const`, `wpU64Const`, `wpI8Const`, `wpI16Const`, `wpI32Const`, and `wpI64Const`
- `wpPrngXorshiftInitWithSeed` to allow for user control with PRNG
### Changed
- Switched to using `wpMiscUtilsRotl64` in `xorshift`
## [2.4.0] - 2026-08-30 ## [2.4.0] - 2026-08-30
+25 -16
View File
@@ -4,6 +4,7 @@
#include "../../common/aliases/aliases.h" #include "../../common/aliases/aliases.h"
#include "../../common/assert/assert.h" #include "../../common/assert/assert.h"
#include "../../common/platform/platform.h" #include "../../common/platform/platform.h"
#include "../../common/misc/misc_utils.h"
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
@@ -12,16 +13,19 @@ struct SplitMix64State {
u64 seed; u64 seed;
}; };
wp_intern u64 rol64(u64 x, u64 bits);
wp_intern u64 split_mix_64(SplitMix64State *state); wp_intern u64 split_mix_64(SplitMix64State *state);
wp_intern void seed_os_generator(void); wp_intern void seed_os_generator(u64 seed);
wp_intern u64 generate_random_number(void); wp_intern u64 generate_random_number(void);
WpXor256State wpPrngXorshiftInit(void) { WpXor256State wpPrngXorshiftInit(void) {
return wpPrngXorshiftInitWithSeed(0);
}
WpXor256State wpPrngXorshiftInitWithSeed(u64 seed) {
wp_persist b8 seeded = false; wp_persist b8 seeded = false;
if (!seeded) { if (!seeded) {
seeded = true; seeded = true;
seed_os_generator(); seed_os_generator(seed);
} }
SplitMix64State sm64 = {.seed = generate_random_number()}; SplitMix64State sm64 = {.seed = generate_random_number()};
@@ -46,7 +50,7 @@ u64 wpPrngXorshift256(WpXor256State *state) {
} }
u64 wpPrngXorshift256ss(WpXor256State *state) { u64 wpPrngXorshift256ss(WpXor256State *state) {
const u64 result = rol64(state->z * 5, 7) * 9; const u64 result = wpMiscUtilsRotl64(state->z * 5, 7) * 9;
const u64 t = state->z << 17; const u64 t = state->z << 17;
state->y ^= state->w; state->y ^= state->w;
@@ -55,7 +59,7 @@ u64 wpPrngXorshift256ss(WpXor256State *state) {
state->w ^= state->x; state->w ^= state->x;
state->y ^= t; state->y ^= t;
state->x = rol64(state->x, 45); state->x = wpMiscUtilsRotl64(state->x, 45);
return result; return result;
} }
@@ -70,15 +74,11 @@ u64 wpPrngXorshift256p(WpXor256State *state) {
state->w ^= state->x; state->w ^= state->x;
state->y ^= t; state->y ^= t;
state->x = rol64(state->x, 45); state->x = wpMiscUtilsRotl64(state->x, 45);
return result; return result;
} }
wp_intern u64 rol64(u64 x, u64 bits) {
return (x << bits) | (x >> (64 - bits));
}
wp_intern u64 split_mix_64(SplitMix64State *state) { wp_intern u64 split_mix_64(SplitMix64State *state) {
state->seed += 0x9E3779B97f4A7C15; state->seed += 0x9E3779B97f4A7C15;
@@ -91,24 +91,30 @@ wp_intern u64 split_mix_64(SplitMix64State *state) {
#if defined(WP_PLATFORM_C) && WP_PLATFORM_C_VERSION >= WP_PLATFORM_C11_VERSION #if defined(WP_PLATFORM_C) && WP_PLATFORM_C_VERSION >= WP_PLATFORM_C11_VERSION
#ifdef WP_PLATFORM_POSIX #ifdef WP_PLATFORM_POSIX
wp_intern void seed_os_generator(void) { wp_intern void seed_os_generator(u64 seed) {
if (seed == 0) {
struct timespec ts = {0}; struct timespec ts = {0};
int result = clock_gettime(CLOCK_MONOTONIC_RAW, &ts); int result = clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
wpRuntimeAssert(result == 0, "Invalid seed value"); wpRuntimeAssert(result == 0, "Invalid seed value");
seed = (u64)ts.tv_nsec;
}
srand48(ts.tv_nsec); srand48(seed);
} }
wp_intern u64 generate_random_number(void) { wp_intern u64 generate_random_number(void) {
return lrand48(); return lrand48();
} }
#else #else
wp_intern void seed_os_generator(void) { wp_intern void seed_os_generator(u64 seed) {
if (seed == 0) {
struct timespec ts = {0}; struct timespec ts = {0};
int result = timespec_get(&ts, TIME_UTC); int result = timespec_get(&ts, TIME_UTC);
wpRuntimeAssert(result != 0, "Invalid seed value"); wpRuntimeAssert(result != 0, "Invalid seed value");
seed = (u64)ts.tv_nsec;
}
srand(ts.tv_nsec); srand(seed);
} }
wp_intern u64 generate_random_number(void) { wp_intern u64 generate_random_number(void) {
@@ -119,11 +125,14 @@ wp_intern u64 generate_random_number(void) {
} }
#endif // !WP_PLATFORM_POSIX #endif // !WP_PLATFORM_POSIX
#else #else
wp_intern void seed_os_generator(void) { wp_intern void seed_os_generator(u64 seed) {
if (seed == 0) {
time_t result = time(NULL); time_t result = time(NULL);
wpRuntimeAssert(result != (time_t)(-1), "Invalid seed value"); wpRuntimeAssert(result != (time_t)(-1), "Invalid seed value");
seed = (u64)result;
}
srand(result); srand(seed);
} }
wp_intern u64 generate_random_number(void) { wp_intern u64 generate_random_number(void) {
+1
View File
@@ -19,6 +19,7 @@ struct WpXor256State {
}; };
WpXor256State wpPrngXorshiftInit(void); WpXor256State wpPrngXorshiftInit(void);
WpXor256State wpPrngXorshiftInitWithSeed(u64 seed);
u64 wpPrngXorshift256(WpXor256State *state); u64 wpPrngXorshift256(WpXor256State *state);
u64 wpPrngXorshift256ss(WpXor256State *state); u64 wpPrngXorshift256ss(WpXor256State *state);
u64 wpPrngXorshift256p(WpXor256State *state); u64 wpPrngXorshift256p(WpXor256State *state);