Add xoshiro256** generator

This commit is contained in:
Abdelrahman Said 2024-03-22 11:52:56 +00:00
parent 2708825924
commit f4afa5d7ea

View File

@ -11,8 +11,21 @@ typedef struct {
u64 w; u64 w;
} XORShift256; } XORShift256;
void test_xorshift_256(Pixel *data, u64 w, u64 h); typedef struct {
u64 xorshift_256_generate(XORShift256 *state); 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[]) { int main(int argc, char *argv[]) {
struct timespec ts = {0}; struct timespec ts = {0};
@ -25,14 +38,22 @@ int main(int argc, char *argv[]) {
u64 length = w * h; u64 length = w * h;
Pixel data[length]; 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; return EXIT_SUCCESS;
} }
void test_xorshift_256(Pixel *data, u64 w, u64 h) { void test_xorshift_256(Image *img) {
XORShift256 state = { XORShift256 state = {
.x = lrand48(), .x = lrand48(),
.y = lrand48(), .y = lrand48(),
@ -40,21 +61,12 @@ void test_xorshift_256(Pixel *data, u64 w, u64 h) {
.w = lrand48(), .w = lrand48(),
}; };
for (u64 y = 0; y < h; ++y) { write_image_data(img, xorshift_256_generate, (void *)&state);
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,
};
}
}
} }
u64 xorshift_256_generate(XORShift256 *state) { u64 xorshift_256_generate(void *s) {
XORShift256 *state = (XORShift256 *)s;
u64 t = state->x ^ (state->x << 11); u64 t = state->x ^ (state->x << 11);
state->x = state->y; state->x = state->y;
@ -64,3 +76,48 @@ u64 xorshift_256_generate(XORShift256 *state) {
return state->w; 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,
};
}
}
}