Pages: [1]   Go Down
Author Topic: Leonardo 3x faster than the Duemillinove?  (Read 396 times)
0 Members and 1 Guest are viewing this topic.
Canby, OR
Offline Offline
Full Member
***
Karma: 1
Posts: 158
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
long start = 0;
long max_seconds = 30;
long i = 2; // Start at 2

void setup() {
  Serial.begin(9600);
 
  while (!Serial) { }
 
  start = millis();
}

long found = 0; // Number we found

void 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?
Logged

Switzerland
Offline Offline
Sr. Member
****
Karma: 6
Posts: 375
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Canby, OR
Offline Offline
Full Member
***
Karma: 1
Posts: 158
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
long start = 0;
long max_seconds = 30;
long i = 2; // Start at 2

void setup() {
  Serial.begin(9600);
 
  while (!Serial) { }
 
  start = millis();
}

long found = 0; // Number we found

void 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
}
Logged

Pages: [1]   Go Up
Jump to: