commit 45342ac49d310d3666381c57f28359b061c1af67 Author: Dmitry Kokorin Date: Wed Nov 30 15:32:54 2016 +0300 initial implementation of xorshift128 and xorshift128plus diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0c38a97 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.o +*.a +a.out +benchmark + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..83c6ca7 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +This repo contains an implementations of [xorshift-family](https://en.wikipedia.org/wiki/Xorshift) random number generators. diff --git a/benchmark.c b/benchmark.c new file mode 100644 index 0000000..ea0debd --- /dev/null +++ b/benchmark.c @@ -0,0 +1,46 @@ +#include +#include + +#include "xorshift.h" + +struct timespec clock_diff(struct timespec start, struct timespec stop) +{ + struct timespec diff; + if ((stop.tv_nsec-start.tv_nsec) < 0) { + + diff.tv_sec = stop.tv_sec - start.tv_sec - 1; + diff.tv_nsec = 1e9 + stop.tv_nsec - start.tv_nsec; + + } else { + + diff.tv_sec = stop.tv_sec - start.tv_sec; + diff.tv_nsec = stop.tv_nsec - start.tv_nsec; + } + + return diff; +} + + +#define BENCHMARK(func) \ +{ \ + struct timespec start, stop, diff; \ + \ + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); \ + \ + for (size_t i = 0; i < 1e9; ++i) \ + (void)func(); \ + \ + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &stop); \ + diff = clock_diff(start, stop); \ + \ + printf("%ld:%ld\n", (long)diff.tv_sec, (long)diff.tv_nsec); \ +} \ + + +int main() +{ + BENCHMARK(xorshift128); + BENCHMARK(xorshift128plus); + + return 0; +} diff --git a/xorshift.c b/xorshift.c new file mode 100644 index 0000000..f3a8882 --- /dev/null +++ b/xorshift.c @@ -0,0 +1,54 @@ +#include "xorshift.h" + +#include +#include + +static uint32_t xorshift128_seed[4] = {1, 1, 1, 1}; +static uint64_t xorshift128plus_seed[2] = {1, 1}; + +void set_xorshift128_seed(uint32_t seed[4]) +{ + for (size_t i = 0; i < 4; ++i) { + + assert(seed[i] != (uint32_t)0); + xorshift128_seed[i] = seed[i]; + } +} + +uint32_t xorshift128() +{ + uint32_t t = xorshift128_seed[0]; + + t ^= t << 11; + t ^= t >> 8; + + xorshift128_seed[0] = xorshift128_seed[1]; + xorshift128_seed[1] = xorshift128_seed[2]; + xorshift128_seed[2] = xorshift128_seed[3]; + + xorshift128_seed[3] ^= xorshift128_seed[3] >> 19; + xorshift128_seed[3] ^= t; + return xorshift128_seed[3]; +} + + +void set_xorshift128plus_seed(uint64_t seed[2]) +{ + for (size_t i = 0; i < 2; ++i) { + + assert(seed[i] != (uint64_t)0); + xorshift128plus_seed[i] = seed[i]; + } +} + +uint64_t xorshift128plus() +{ + uint64_t x = xorshift128plus_seed[0]; + uint64_t const y = xorshift128plus_seed[1]; + + xorshift128plus_seed[0] = y; + x ^= x << 23; + xorshift128plus_seed[1] = x ^ y ^ (x >> 17) ^ (y >> 26); + + return xorshift128plus_seed[1] + y; +} diff --git a/xorshift.h b/xorshift.h new file mode 100644 index 0000000..9e5f3c5 --- /dev/null +++ b/xorshift.h @@ -0,0 +1,14 @@ +#ifndef _XORSHIFT_H_ +#define _XORSHIFT_H_ + +#include + + +void set_xorshift128_seed(uint32_t seed[4]); +uint32_t xorshift128(); + +void set_xorshift128plus_seed(uint64_t seed[2]); +uint64_t xorshift128plus(); + + +#endif