Go Down

Topic: Speed Test (Read 2205 times) previous topic - next topic

haxan7

I recently bought an Arduino Due, and I worked up this code to compare the speeds of Due and Uno.

Code: [Select]
#include <stdint.h>

void setup() {
 
  /*
  Results
  My Due = 7425986u = 7427m
  My Uno = 24591260u = 24591m
  */
 
  // put your setup code here, to run once:
  pinMode(13, OUTPUT);
 
  Serial.begin(115200);
  while(!Serial);
  Serial.println("Start");
 
  float a = 0.2;
  float b = 0.3;
  /* 0 to 4,294,967,295 */
  uint32_t startMicros = micros();
  uint32_t startMillis = millis();
  for(uint32_t i=0;i<10000;i++){
    for(uint32_t j=0;j<100;j++){
      a = b = (digitalRead(2)+2);
      b = a*(digitalRead(2)+1);
      a = b*(digitalRead(2)-1);
      a = a*1.5*(digitalRead(2)-5);
      b = b*1.5+(digitalRead(2)-200);
      a = b*a;
      if(a>2.3 && b<0.5){
        digitalWrite(13, HIGH);
      }else{
        digitalWrite(13, HIGH);
      }
    }
  }
  Serial.print("Micros = ");Serial.println(micros()-startMicros);
  Serial.print("Millis = ");Serial.println(millis()-startMillis);
  Serial.println("End");
 
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(100);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(100);
}


Given the clock speed and 32 bit controller of the due. I has hoping for a difference of 84/16 * 4 = 21 Times. But my experiment returned that my Due is only 3.3 times faster than my uno.

Am I missing something here? I am starting to suspect that I have received a fake Due. Can anybody post their result by running this code.

pjrc

#1
Feb 11, 2015, 09:43 am Last Edit: Feb 11, 2015, 09:52 am by Paul Stoffregen
The slowness is probably in digitalRead and digitalWrite.

I just ran it here on a Teensy 3.1.

Code: [Select]

Start
Micros = 1117377
Millis = 1117
End


Then I tried changing all the digitalRead and digitalWrite to digitalReadFast and digitalWriteFast.  The result with the fast functons:

Code: [Select]

Start
Micros = 188206
Millis = 188
End


But that seems too fast to be true.  So I tried another run, with two Serial.println() added after the test, to print the values of a and b.

Code: [Select]

Start
Micros = 11313829
Millis = 11314
End
-2955.00
-197.00


So it seems the compiler "knows" the values of a and b aren't ever used, so it's not bothering to actually perform most of the calculations.

Here's the full modified code.  I'd recommend running this on both your boards.

Code: [Select]

#include <stdint.h>

void setup() {
 
  /*
  Results
  My Due = 7425986u = 7427m
  My Uno = 24591260u = 24591m
  */
 
  // put your setup code here, to run once:
  pinMode(13, OUTPUT);
  pinMode(2, INPUT);
 
  Serial.begin(115200);
  while(!Serial);
  Serial.println("Start");
 
  float a = 0.2;
  float b = 0.3;
  /* 0 to 4,294,967,295 */
  uint32_t startMicros = micros();
  uint32_t startMillis = millis();
  for(uint32_t i=0;i<10000;i++){
    for(uint32_t j=0;j<100;j++){
      a = b = (digitalReadFast(2)+2);
      b = a*(digitalReadFast(2)+1);
      a = b*(digitalReadFast(2)-1);
      a = a*1.5*(digitalReadFast(2)-5);
      b = b*1.5+(digitalReadFast(2)-200);
      a = b*a;
      if(a>2.3 && b<0.5){
        digitalWriteFast(13, HIGH);
      }else{
        digitalWriteFast(13, HIGH);
      }
    }
  }
  Serial.print("Micros = ");Serial.println(micros()-startMicros);
  Serial.print("Millis = ");Serial.println(millis()-startMillis);
  Serial.println("End");
  Serial.println(a);
  Serial.println(b);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWriteFast(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(100);              // wait for a second
  digitalWriteFast(13, LOW);    // turn the LED off by making the voltage LOW
  delay(100);
}


Normal Arduino boards don't have digitalWriteFast built in, so you'll have to find the library that adds it, or just change back to normal digitalRead and digitalWrite.

Here is the test run one more time on Teensy 3.1, with the slower digitalRead and digitalWrite

Code: [Select]

Start
Micros = 12483028
Millis = 12483
End
-2955.00
-197.00


Measuring performance is tricky business.  It's easy to end up with wrong results, because the compiler is crafty about optimizing away unnecessary work, and because functions you think would be fast can actually end up obscuring the actual CPU speed.

MorganS

The 32-bit words used by the Due might be 4 times faster than the Uno 8 bits but only for calculations. Logic code like the if and the loop won't get the same speedup.

Try something with an integer division in it. This is really slow on the Uno. Sometimes the Uno's floating point division is faster than its integers. The Due supposedly has hardware division.

Multiplying by 1.5 in your code will force a floating point conversion. I don't know if this is a slow function on the Due.
"The problem is in the code you didn't post."

Go Up