diff --git a/C/README.md b/C/README.md index 261ef8a7..5f7a7035 100644 --- a/C/README.md +++ b/C/README.md @@ -12,7 +12,7 @@ This repository contains a few implementations of a simple botec (back-of-the-en - [ ] Add CUDA? - [x] Added results of perf. `rand_r` seems like a big chunk of it, but I'm hesitant to use lower-quality random numbers - [x] used xorshift instead - - [ ] Use xorshift with a struct instead of a pointer? idk, could be faster for some reason? + - [-] Use xorshift with a struct instead of a pointer? idk, could be faster for some reason? => Tested, it takes the same time. - [x] Update repository with correct timing - [x] Use better profiling approach to capture timing with 1M samples. - [x] See if program can be reworded so as to use multithreading effectively, e.g., so that you see speed gains proportional to the number of threads used diff --git a/C/samples.c b/C/samples.c index b1d2e96e..e9f13702 100644 --- a/C/samples.c +++ b/C/samples.c @@ -84,6 +84,8 @@ uint32_t xorshift32(uint32_t* seed) // Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" // See // https://en.wikipedia.org/wiki/Xorshift + // Also some drama: , + uint32_t x = *seed; x ^= x << 13; x ^= x >> 17; diff --git a/C/scratchpad/makefile b/C/scratchpad/makefile deleted file mode 100644 index 819c0de8..00000000 --- a/C/scratchpad/makefile +++ /dev/null @@ -1,2 +0,0 @@ -build: - gcc xorshift.c -o xorshift diff --git a/C/xorshift-scratchpad/makefile b/C/xorshift-scratchpad/makefile new file mode 100644 index 00000000..50e4d4b2 --- /dev/null +++ b/C/xorshift-scratchpad/makefile @@ -0,0 +1,15 @@ +build: + gcc xorshift-pointer.c -o out/xorshift-pointer + gcc xorshift-struct.c -o out/xorshift-struct + +run-pointer: + ./out/xorshift-pointer + +run-struct: + ./out/xorshift-struct + +time-pointer: + /bin/time -f "Time: %es" ./out/xorshift-pointer && echo + +time-struct: + /bin/time -f "Time: %es" ./out/xorshift-struct && echo diff --git a/C/xorshift-scratchpad/notes.md b/C/xorshift-scratchpad/notes.md new file mode 100644 index 00000000..ac64d1d9 --- /dev/null +++ b/C/xorshift-scratchpad/notes.md @@ -0,0 +1 @@ +Using a pointer or a struct turns out to be pretty equivalent in terms of speed. I don't think there are gains to be found here, but I find the pointer implementation clearer. diff --git a/C/scratchpad/xorshift b/C/xorshift-scratchpad/out/xorshift-pointer similarity index 53% rename from C/scratchpad/xorshift rename to C/xorshift-scratchpad/out/xorshift-pointer index 2a32b0b1..9f5c4c34 100755 Binary files a/C/scratchpad/xorshift and b/C/xorshift-scratchpad/out/xorshift-pointer differ diff --git a/C/xorshift-scratchpad/out/xorshift-struct b/C/xorshift-scratchpad/out/xorshift-struct new file mode 100755 index 00000000..3c0af4ab Binary files /dev/null and b/C/xorshift-scratchpad/out/xorshift-struct differ diff --git a/C/scratchpad/xorshift.c b/C/xorshift-scratchpad/xorshift-pointer.c similarity index 78% rename from C/scratchpad/xorshift.c rename to C/xorshift-scratchpad/xorshift-pointer.c index b476c702..723b9a42 100644 --- a/C/scratchpad/xorshift.c +++ b/C/xorshift-scratchpad/xorshift-pointer.c @@ -20,13 +20,15 @@ int main(){ uint32_t** states = malloc(4 * sizeof(uint32_t*)); for(int i=0; i<4;i++){ states[i] = malloc(sizeof(uint32_t)); - *states[i] = i + 1; + *states[i] = (uint32_t) i + 1; + } + for(int i=0; i<1000000000;i++){ + uint32_t x = xorshift32(states[0]); + float y = rand_xorshift32(states[1]); + // printf("%u\n", x); + // printf("%f\n", y); } - for(int i=0; i<100; i++){ - printf("%u\n", xorshift32(states[0])); - printf("%f\n", rand_xorshift32(states[1])); - } for(int i=0; i<4;i++){ free(states[i]); } diff --git a/C/xorshift-scratchpad/xorshift-struct.c b/C/xorshift-scratchpad/xorshift-struct.c new file mode 100644 index 00000000..6042bd3e --- /dev/null +++ b/C/xorshift-scratchpad/xorshift-struct.c @@ -0,0 +1,46 @@ +#include +#include +#include + +struct xorshift32_state { + uint32_t a; +}; + +uint32_t xorshift32(struct xorshift32_state *state) +{ + /* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */ + uint32_t x = state->a; + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + return state->a = x; +} + +float rand_xorshift32(struct xorshift32_state *state){ + return (float) xorshift32(state) / (float) UINT32_MAX; +} + + +int main(){ + struct xorshift32_state** states = malloc(sizeof(struct xorshift32_state*) * 4); + for(int i=0; i<4;i++){ + states[i] = malloc(sizeof(struct xorshift32_state)); + states[i]->a = (uint32_t) i + 1; + } + + for(int i=0; i<1000000000; i++){ + uint32_t x = xorshift32(states[0]); + float y = rand_xorshift32(states[1]); + // printf("%u\n", x); + // printf("%f\n", y); + } + + for(int i=0; i<4;i++){ + free(states[i]); + } + free(states); + + + return 0; +} +