Go Down

Topic: Leonardo 3x faster than the Duemillinove? (Read 654 times)previous topic - next topic

scottchiefbaker

Sep 11, 2012, 07:52 am
I whipped up a really simple benchmark, calculating primes, and ran it on my Duemillinove and my Leonardo. The Leonardo performed more than 3x better than my Duemillinove. Is the Leonardo really that much faster!?!

Code: [Select]
`long start = 0;long max_seconds = 30;long i = 2; // Start at 2void setup() {  Serial.begin(9600);     while (!Serial) { }    start = millis();}long found = 0; // Number we foundvoid loop() {  int prime = is_prime(i); // Check if the number we're on is prime  if (prime == 1) {     Serial.print(i);    Serial.println(" is prime ");        found++;  }    int running_seconds = (millis() - start) / 1000;    if (max_seconds > 0 && (running_seconds >= max_seconds)) {    Serial.print("Found ");    Serial.print(found);    Serial.print(" primes in ");    Serial.print(max_seconds);    Serial.println(" seconds");    while(1) { }   }  i++;}int is_prime(int num) {  // Only have to check for divisible for the sqrt(number)  long upper = sqrt(num);  // Check if the number is evenly divisible (start at 2 going up)  for (long cnum = 2; cnum <= upper; cnum++) {    long mod = num % cnum; // Remainder    if (mod == 0) {       return 0;     } // If the remainer is 0 it's evenly divisible  }  return 1; // If you get this far it's prime}`

Leonardo: Found 6078 primes in 30 seconds
Duemillinove: Found 1785 primes in 30 seconds

Maybe something is wrong with my code?

tim7

#1
Sep 11, 2012, 08:17 am
The Leonardo's instruction set is the same, so the calculation should run at the same speed.  However the USB "serial" interface is much faster: the data is never actually sent as old-fashioned serial, and the effective transmission rate is much higher than 9600 baud.

On the Duemillanove the serial conversion is a bottleneck.
If I run your code on an Uno at 9600 baud I get the same result as you: Found 1785 primes in 30 seconds
If I bump the baud up to 115200 I get: Found 4298 primes in 30 s

scottchiefbaker

#2
Sep 12, 2012, 02:49 am
You were exactly right! I didn't even think of serial being a limitation, good catch. Also I found a bug in my code, where checking primes about 32k always returned true. Here is updated code, which now perform roughly the same on both boards.

Code: [Select]
`long start = 0;long max_seconds = 30;long i = 2; // Start at 2void setup() {  Serial.begin(9600);     while (!Serial) { }    start = millis();}long found = 0; // Number we foundvoid loop() {  int prime = is_prime(i); // Check if the number we're on is prime  if (prime == 1) {     Serial.print(i);    Serial.println(" is prime ");        found++;  }    int running_seconds = (millis() - start) / 1000;    if (max_seconds > 0 && (running_seconds >= max_seconds)) {    Serial.print("Found ");    Serial.print(found);    Serial.print(" primes in ");    Serial.print(max_seconds);    Serial.println(" seconds");    while(1) { }   }  i++;}int is_prime(long num) {  // Only have to check for divisible for the sqrt(number)  int upper = sqrt(num);    // Check if the number is evenly divisible (start at 2 going up)  for (long cnum = 2; cnum <= upper; cnum++) {    long mod = num % cnum; // Remainder        if (mod == 0) {       return 0;     } // If the remainer is 0 it's evenly divisible  }  return 1; // If you get this far it's prime}`

Go Up