time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

commit 1436ee4e42cc0d327a92f5fd25552f6f6d14d686
parent a7bb3bc812f7dffc67a448be3fe6538bddaaf6c1
Author: NunoSempere <nuno.sempere@protonmail.com>
Date:   Sat,  3 Jun 2023 10:50:06 -0600

compare using a struct instead of a pointer, reorg

Diffstat:
MC/README.md | 2+-
MC/samples.c | 2++
DC/scratchpad/makefile | 2--
DC/scratchpad/xorshift | 0
DC/scratchpad/xorshift.c | 39---------------------------------------
AC/xorshift-scratchpad/makefile | 15+++++++++++++++
AC/xorshift-scratchpad/notes.md | 1+
AC/xorshift-scratchpad/out/xorshift-pointer | 0
AC/xorshift-scratchpad/out/xorshift-struct | 0
AC/xorshift-scratchpad/xorshift-pointer.c | 41+++++++++++++++++++++++++++++++++++++++++
AC/xorshift-scratchpad/xorshift-struct.c | 46++++++++++++++++++++++++++++++++++++++++++++++
11 files changed, 106 insertions(+), 42 deletions(-)

diff --git 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 @@ -84,6 +84,8 @@ uint32_t xorshift32(uint32_t* seed) // Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" // See <https://stackoverflow.com/questions/53886131/how-does-xorshift32-works> // https://en.wikipedia.org/wiki/Xorshift + // Also some drama: <https://www.pcg-random.org/posts/on-vignas-pcg-critique.html>, <https://prng.di.unimi.it/> + uint32_t x = *seed; x ^= x << 13; x ^= x >> 17; diff --git a/C/scratchpad/makefile b/C/scratchpad/makefile @@ -1,2 +0,0 @@ -build: - gcc xorshift.c -o xorshift diff --git a/C/scratchpad/xorshift b/C/scratchpad/xorshift Binary files differ. diff --git a/C/scratchpad/xorshift.c b/C/scratchpad/xorshift.c @@ -1,39 +0,0 @@ -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> - -uint32_t xorshift32(uint32_t* state) -{ - /* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */ - uint32_t x = *state; - x ^= x << 13; - x ^= x >> 17; - x ^= x << 5; - return *state = x; -} - -float rand_xorshift32(uint32_t* state){ - return (float) xorshift32(state) / (float) UINT32_MAX; -} - -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; - } - - 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]); - } - free(states); - - return 0; -} - -// See <https://stackoverflow.com/questions/53886131/how-does-xorshift32-works> -// https://en.wikipedia.org/wiki/Xorshift diff --git a/C/xorshift-scratchpad/makefile 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 @@ -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/xorshift-scratchpad/out/xorshift-pointer b/C/xorshift-scratchpad/out/xorshift-pointer Binary files differ. diff --git a/C/xorshift-scratchpad/out/xorshift-struct b/C/xorshift-scratchpad/out/xorshift-struct Binary files differ. diff --git a/C/xorshift-scratchpad/xorshift-pointer.c b/C/xorshift-scratchpad/xorshift-pointer.c @@ -0,0 +1,41 @@ +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +uint32_t xorshift32(uint32_t* state) +{ + /* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */ + uint32_t x = *state; + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + return *state = x; +} + +float rand_xorshift32(uint32_t* state){ + return (float) xorshift32(state) / (float) UINT32_MAX; +} + +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] = (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; +} + +// See <https://stackoverflow.com/questions/53886131/how-does-xorshift32-works> +// https://en.wikipedia.org/wiki/Xorshift diff --git a/C/xorshift-scratchpad/xorshift-struct.c b/C/xorshift-scratchpad/xorshift-struct.c @@ -0,0 +1,46 @@ +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +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; +} +