From f4afa5d7eacba243f5b551b6a74e4dedbfd9d0d3 Mon Sep 17 00:00:00 2001 From: Abdelrahman Said Date: Fri, 22 Mar 2024 11:52:56 +0000 Subject: [PATCH] Add xoshiro256** generator --- xorshift.c | 93 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 75 insertions(+), 18 deletions(-) diff --git a/xorshift.c b/xorshift.c index cc21dc6..d597294 100644 --- a/xorshift.c +++ b/xorshift.c @@ -11,8 +11,21 @@ typedef struct { u64 w; } XORShift256; -void test_xorshift_256(Pixel *data, u64 w, u64 h); -u64 xorshift_256_generate(XORShift256 *state); +typedef struct { + u64 x; + u64 y; + u64 z; + u64 w; +} XOShiRo256SS; + +typedef u64(RandGenFunc)(void *s); + +void test_xorshift_256(Image *img); +u64 xorshift_256_generate(void *s); +void test_xoshiro_256ss(Image *img); +u64 xoshiro_256ss_generate(void *s); +u64 rol64(u64 x, u64 bits); +void write_image_data(Image *img, RandGenFunc *gen_rand, void *s); int main(int argc, char *argv[]) { struct timespec ts = {0}; @@ -25,14 +38,22 @@ int main(int argc, char *argv[]) { u64 length = w * h; Pixel data[length]; - test_xorshift_256(data, w, h); + Image img = { + .width = w, + .height = h, + .data = data, + }; - write_p6_ppm("./outputs/xorshift_256.ppm", w, h, data); + test_xorshift_256(&img); + write_p6_ppm("./outputs/xorshift256.ppm", &img); + + test_xoshiro_256ss(&img); + write_p6_ppm("./outputs/xoshiro256ss.ppm", &img); return EXIT_SUCCESS; } -void test_xorshift_256(Pixel *data, u64 w, u64 h) { +void test_xorshift_256(Image *img) { XORShift256 state = { .x = lrand48(), .y = lrand48(), @@ -40,21 +61,12 @@ void test_xorshift_256(Pixel *data, u64 w, u64 h) { .w = lrand48(), }; - for (u64 y = 0; y < h; ++y) { - for (u64 x = 0; x < w; ++x) { - u64 i = y * w + x; - - u8 pixel = xorshift_256_generate(&state) % UINT8_MAX; - data[i] = (Pixel){ - .r = pixel, - .g = pixel, - .b = pixel, - }; - } - } + write_image_data(img, xorshift_256_generate, (void *)&state); } -u64 xorshift_256_generate(XORShift256 *state) { +u64 xorshift_256_generate(void *s) { + XORShift256 *state = (XORShift256 *)s; + u64 t = state->x ^ (state->x << 11); state->x = state->y; @@ -64,3 +76,48 @@ u64 xorshift_256_generate(XORShift256 *state) { return state->w; } + +void test_xoshiro_256ss(Image *img) { + XOShiRo256SS state = { + .x = lrand48(), + .y = lrand48(), + .z = lrand48(), + .w = lrand48(), + }; + + write_image_data(img, xoshiro_256ss_generate, (void *)&state); +} + +u64 xoshiro_256ss_generate(void *s) { + XOShiRo256SS *state = (XOShiRo256SS *)s; + + const u64 result = rol64(state->z * 5, 7) * 9; + const u64 t = state->z << 17; + + state->y ^= state->w; + state->x ^= state->z; + state->z ^= state->y; + state->w ^= state->x; + + state->y ^= t; + state->x = rol64(state->x, 45); + + return result; +} + +u64 rol64(u64 x, u64 bits) { return (x << bits) | (x >> (64 - bits)); } + +void write_image_data(Image *img, RandGenFunc *gen_rand, void *s) { + for (u64 y = 0; y < img->height; ++y) { + for (u64 x = 0; x < img->width; ++x) { + u64 i = y * img->width + x; + + u8 pixel = gen_rand(s) % UINT8_MAX; + img->data[i] = (Pixel){ + .r = pixel, + .g = pixel, + .b = pixel, + }; + } + } +}