Archiv der Kategorie: STM32

Vergleich Maple vs Arduino*

maple1

Zugegebenermaßen ein wirklich unfairer Vergleich, was sollte man schon bei dem Vergleich eines STM32 mit 32Bit und 72MHz Taktfrequenz gegen einen 8Bit Atmel mit 16MHz erwarten? Der Erstere ist natürlich schneller – aber wieviel schneller?

Zunächst geht es erst mal darum möglichst gleiche Ausgangspositionen zu schaffen. Für den Vergleich wählte ich ein Programm zur Suche von Primzahlen. Dieses Programm ist der Erweiterung für die Arduino IDE beigefügt. Um den Maple mit der Arduino IDE zu flashen habe ich nach dieser Anleitung die IDE 1.6.0 erweitert. Im Arduino Forum gibt es dazu einen inzwischen über 100 Seiten (!!) langen Post.  Das Flashen ist etwas umständlich, man muss erst den Maple in den Perpetual bootloader mode bringen und nach dem Upload die Reset Taste drücken. Aber es geht hier weniger um die Bedienbarkeit, ich bin ja froh, dass ich überhaupt mit der Arduino IDE arbeiten kann.

Das Programm sucht die Primzahlen bis zu einer gegebenen Zahl. Da ich größere Geschwindigkeitsunterschiede bei großen Zahlen bereits erwartet habe, habe ich zunächst mit uint8_t als Datentyp begonnen.

Hier das Programm, in der Kommentierung sieht man die Unterschiede für beide Prozessoren im Code, die lediglich im setup() vorhanden sind. Damit man überhaupt im Millisekunden Bereich was messen kann, wird die Schleife 255x durchlaufen.

/*
  PrimeNos3: by Nick Gammon
  Maple Mini port m. ray burnette: Compiled under Arduino 1.6.0
  PUBLIC DOMAIN EXAMPLE
*/

#define BAUD 115200
uint8_t limit = 255;

/* Arduino part
#define BOARD_LED_PIN 13
void setup() {
  // initialize the digital pin as an output.
  pinMode(BOARD_LED_PIN, OUTPUT);
  Serial.begin(BAUD);  
  Serial.println("Prime Number Generator V2");
} */  //Arduino part

// Maple part
void setup() {
  // initialize the digital pin as an output.
  pinMode(BOARD_LED_PIN, OUTPUT);
  Serial.begin(BAUD);  // BAUD has no effect on USB serial: placeholder for physical UART
  // wait for serial monitor to be connected.

  while (!(Serial.isConnected() && (Serial.getDTR() || Serial.getRTS())))
  {
    toggleLED();
    delay(100);         // fast blink
  }
  Serial.println("Prime Number Generator V2");
} //   //Maple part

void loop() {
  uint8_t i;
  Serial.print("Searching prime numbers between 1 and "); Serial.println(limit);
  unsigned long starttime = millis();
  for (uint8_t k = 0; k < 255; k++) {
    for (i = 3; i < limit; i += 2) {
      // This loop stops either when j*j>i or when i is divisible by j.
      // The first condition means prime, the second, not prime.
      uint8_t j = 3;
      for (; j * j <= i && i % j != 0; j += 2); // No loop body
      // if (j * j > i) Serial.println(i);      // output prime numbers
    }
  }
  Serial.print("Test run for ");
  Serial.print((millis() - starttime));
  Serial.println(" milliseconds\r\n");
  delay(2000);
}
 

Ergebnis: Arduino UNO 550ms / Maple 30ms  — immerhin also ein Faktor von 18,3 erstaunlich viel, da der Unterschied in der Taktfrequenz ja nur Faktor 4,4 ist.

In nächsten Test habe ich den Datentyp auf uint16_t geändert und die Primzahlen bis zur Grenze von 65535 gesucht. Der 255-malige Durchlauf wurde auf 1x reduziert.

Ergebnis: Arduino UNO 10760ms / Maple 241ms  — also immerhin schon ein Faktor von 44,7. Hier zeigen die 32Bit des STM ihre Wirkung.

Im nächsten Test bin ich dann auf uint32_t und einen Suchbereich bis 2x 65535 gegangen.

Ergebnis: Arduino UNO 84551ms / Maple 583ms  — den Maple mit seinem 32Bit Prozessor kümmert das recht wenig, die Rechenzeit ist erstaunlicherweise nur etwas mehr als doppelt so lang, wie beim vorherigen Grenzwert. Der Arduino quittiert den längeren Datentyp sofort mit einer 7,9x längeren Rechenzeit.

Im letzten Test habe ich dann die Grenze nochmal weiter erhöht, musste den Test aber abbrechen, weil mir die Geduld fehlte, auf den Arduino zu warten. Der Maple rechnete für eine Grenze von 1000000 (eine Million) nur 10042ms.

Die Ergebnisse hier nochmals als Übersicht, alle Zeitangaben in Millisekunden.

Datentyp Suchbereich Arduino Maple
uint8_t 255 550 30
uint16_t 65535 10760 241
uint32_t 2*65535 84551 583
uint32_t 1000000 abgebrochen 10042

Fazit: Dass der Maple soviel schneller bei der Verarbeitung von 32Bit Zahlen ist, habe ich in der Tat nicht erwartet. In Zukunft werde ich bei Performance kritischen Verarbeitungen den Maple sicher mal nutzen. Momentan ist aber die Unterstützung der Standard Libraries noch ziemlich rudimentär, aber das wird sich hoffentlich weiter entwickeln. Arduino bringt mit dem Due ja auch einen 32Bit Prozessor in die Familie.  Auf Dauer geht an 32Bit kein Weg vorbei. Bleibt zu hoffen, dass Arduino die Integration in die IDE und die Entwicklung der Libraries schnell vorantreibt.

*mir ist bewusst, dass die Abbildung keinen Arduino zeigt, sondern einen Arduino Nachbau, Die Messergebnisse sind aber sicher portierbar. Zusätzlich mächte ich betonen, dass ich auch Orginale Arduinos in meiner Sammlung habe und jedem empfehle, mit einem Orginalen anzufangen, um die Idee Arduino zu unterstützen.

Advertisements