Skip to content

Instantly share code, notes, and snippets.

@inad9300
Last active September 10, 2022 13:57
Show Gist options
  • Save inad9300/c392c9e3eeeb09d5fa458fe957a12fb8 to your computer and use it in GitHub Desktop.
Save inad9300/c392c9e3eeeb09d5fa458fe957a12fb8 to your computer and use it in GitHub Desktop.
Home-baked random number generator.
// 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