-
-
Save battlecoder/d89d6ca3abbb91f1ab739e51a6cedfe4 to your computer and use it in GitHub Desktop.
Random Periodicity Test Code for arduino (compiled in Arduino IDE)
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
/* | |
* Test sketch based on rand-period-test.c by @unprovable | |
* His sketch shown an anomaly with Arduino's PRNG, in which the LCG period seems to be unreliable. | |
* Also the function seems to be quite slow; iterating over the stream until we get back to the beginning | |
* takes 199340888ms (55.3724689 hours). It takes 1.5 minutes (approx) to generate 1M numbers. | |
* So I decided to repeat the test with a textbook implementation of a standard LCG to see if we can get a | |
* reliable generator with a stable period (and hopefully faster runtime) under the same conditions. | |
* In my test, this script takes ~47 seconds each 1M numbers, and 103345725 ms (28.707146 hours) in total, | |
* with a period that matches the theoretical expected value of 7FFFFFFF, so if you are going to do random | |
* with an arduino, even a regular standard LCG implementation is way better than what you get out of the | |
* box. | |
* NOTE: Tests performed on an Arduino Nano (Atmega328p processor) @ 16Mhz. | |
*/ | |
long rand_i, rand_j, rand_k; | |
unsigned long i = 0, j = 0, k = 0; | |
long startTime; | |
long lastTime; | |
long now; | |
unsigned long lcg_seed = 0x50000L; // Could be any value | |
unsigned long rand2(){ | |
lcg_seed = (lcg_seed * 1103515245L + 12345L) % 2147483648L; | |
return lcg_seed; | |
} | |
void setup() { | |
// put your setup code here, to run once: | |
rand_i = rand2(); | |
rand_j = rand2(); | |
rand_k = rand2(); | |
Serial.begin(57600); | |
while (!Serial) {} | |
Serial.print("starting num rand_i: "); Serial.println(rand_i, HEX); | |
Serial.print("starting num rand_j: "); Serial.println(rand_j, HEX); | |
Serial.print("starting num rand_k: "); Serial.println(rand_k, HEX); | |
pinMode(LED_BUILTIN, OUTPUT); | |
Serial.print("using rand_k = ");Serial.println(rand_k); | |
startTime = millis(); | |
lastTime = startTime; | |
} | |
void loop() { | |
// put your main code here, to run repeatedly: | |
if ((i % 1000000) == 0) { | |
now = millis(); | |
Serial.print("Up to "); | |
Serial.print(i); | |
Serial.print(" iterations in "); | |
Serial.print((long)(now - lastTime), DEC); | |
Serial.println(" ms"); | |
lastTime = now; | |
} | |
if (rand2() == rand_k) { | |
now = millis(); | |
Serial.print("MATCH!! We got a match on "); Serial.print(rand_k); Serial.print(" in "); Serial.print(i, HEX); Serial.println(" operations."); | |
//i = 0; | |
while(true){ | |
Serial.print("MATCH!! We got a match on "); Serial.print(rand_k); Serial.print(" in "); Serial.print(i, HEX); Serial.println(" operations."); | |
Serial.print("-- It took "); | |
Serial.print((long)(now - startTime), DEC); | |
Serial.println(" ms"); | |
digitalWrite(LED_BUILTIN, HIGH); | |
delay(50000); | |
digitalWrite(LED_BUILTIN, LOW); | |
delay(500); | |
}; // stop the duino so we can see what the magic number is :-P Keep printing in case the serial port goes to sleep... | |
} | |
i++; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you are wondering how this code compares to unprovable's sketch but you don't want to run a diff: This sketch is exactly the same, but it uses a standard LCG (implemented in rand2()) instead of Arduino's random().
It also has a global time counter to know how much time it takes to run this whole thing, which is something I also added to my local copy of his sketch when I ran the test on my Arduino. That's how I know how much time it took, and was able to compare.
If you run mine and unprovable's sketch on an Arduino other than a Nano @ 16Mhz, let me know! It would be quite interesting to know what the performance is like, and what result you get, on other Arduinos, with different processors and/or clock speeds.