Last active
September 10, 2022 13:57
-
-
Save inad9300/c392c9e3eeeb09d5fa458fe957a12fb8 to your computer and use it in GitHub Desktop.
Home-baked random number generator.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// clear && gcc -std=c++17 -pthread -O2 randym.cpp && time ./a.out | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <pthread.h> | |
#include <unistd.h> | |
#include <sys/time.h> | |
using u64 = unsigned long long int; | |
static volatile int bit = 600'000; | |
void* peek(void* data) { | |
printf("peek()\n"); | |
const int target_len = 32; | |
int result[target_len] = {}; | |
for (int i = 0; i < target_len; ++i) { | |
usleep(1000); | |
result[i] = bit; | |
} | |
unsigned int n = 0; | |
for (int i = 0; i < target_len; ++i) { | |
if (result[i] == 1) | |
n = n ^ (1 << i); | |
} | |
printf("\nRandom number: %d\n", n); | |
exit(0); | |
return NULL; | |
} | |
static volatile int flipping = 0; | |
void* flip(void* data) { | |
printf("flip()\n"); | |
flipping = 1; | |
while (1) { | |
// bit ^= 1; | |
bit = bit == 600'000 ? 800'000 : 600'000; | |
} | |
} | |
void peeks_stat_test() { | |
while (!flipping); | |
printf("peeks_stat_test()\n"); | |
u64 ones = 0; | |
u64 zeros = 0; | |
u64 limit = 100'000'000; | |
for (u64 i = 0; i < limit; ++i) { | |
usleep(10); | |
if (bit == 600'000) ones++; | |
else zeros++; | |
if (i % 500'000 == 0 && i != 0) { | |
double sum = (double) ones + zeros; | |
int diff = abs((float) (int) ones - zeros); | |
printf(" Ones: %llu (%f%%)\n", ones, ones * 100.0 / sum); | |
printf(" Zeros: %llu (%f%%)\n", zeros, zeros * 100.0 / sum); | |
printf(" Diff: %d (%f%%)\n", diff, diff * 100.0 / sum); | |
printf(" ---\n"); | |
} | |
} | |
double sum = (double) ones + zeros; | |
int diff = (int) ones - zeros; | |
printf(" Ones: %llu (%f%%)\n", ones, ones * 100.0 / sum); | |
printf(" Zeros: %llu (%f%%)\n", zeros, zeros * 100.0 / sum); | |
printf(" Diff: %d (%f%%)\n", diff, diff * 100.0 / sum); | |
} | |
double timeval_diff(const timeval& t1, const timeval& t2) { | |
double t = (t2.tv_sec - t1.tv_sec) * 1000.0; | |
t += (t2.tv_usec - t1.tv_usec) / 1000.0; | |
return t; | |
} | |
void flips_per_ms_test() { | |
printf("flips_per_ms_test()\n"); | |
u64 limit = 100'000'000; | |
volatile int testBit = 0; | |
struct timeval t1, t2, t3, t4, t5; | |
gettimeofday(&t1, NULL); | |
for (u64 i = 0; i < limit; ++i) testBit ^= 1; | |
gettimeofday(&t2, NULL); | |
for (u64 i = 0; i < limit; ++i) testBit = !testBit; | |
gettimeofday(&t3, NULL); | |
for (u64 i = 0; i < limit; ++i) testBit = testBit == 0 ? 1 : 0; | |
gettimeofday(&t4, NULL); | |
for (u64 i = 0; i < limit; ++i) testBit = testBit == 1 ? 0 : 1; | |
gettimeofday(&t5, NULL); | |
double xor_t = timeval_diff(t1, t2); | |
double not_t = timeval_diff(t2, t3); | |
double zero_t = timeval_diff(t3, t4); | |
double one_t = timeval_diff(t4, t5); | |
printf(" `bit ^ 1`: %f ms (%f ops/ms)\n", xor_t, limit / xor_t); | |
printf(" `!bit`: %f ms (%f ops/ms)\n", not_t, limit / not_t); | |
printf(" `bit == 0`: %f ms (%f ops/ms)\n", zero_t, limit / zero_t); | |
printf(" `bit == 1`: %f ms (%f ops/ms)\n", one_t, limit / one_t); | |
} | |
int main() { | |
flips_per_ms_test(); | |
pthread_t fliper; | |
pthread_create(&fliper, NULL, flip, NULL); | |
peeks_stat_test(); | |
pthread_t peeker; | |
pthread_create(&peeker, NULL, peek, NULL); | |
pthread_join(peeker, NULL); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment