für Due: Benchmark Test für verschiedene MCUs

hallo,
ich habe einen Benchmarktest für einen ARM7 und einen ARM9 Microcomputer geschrieben, und mich würde interessieren, ob man ihn auch auf einen Due portieren kann.
Er ist teilw. sehr speicherintensiv (Kopier- und Sortier-Tests von 3 verschiedenen int array[500]), wenn das den Specher überfordert, könnte man auch die Teil-Tests weglassen. (edit - sah gerade: 96kB RAM - das reicht 100%ig !)

Der Code ist leider zu lang um ihn hier zu posten, daher verlinke ich ihn hier - er liegt u.a. vor für

  • nxtOSEK TOPPERS/ATK C/C++ (ARM7 NXT) und
  • gpp C/C++ mit CSLite Toolchains 2009 (ARM9 EV3)
  • daneben auch in Java und einigen anderen VM-basierten Sprachen in C-ähnlicher Syntax

Wäre wirklich super, wenn man jetzt auch mal einen Arduino im Testpaket mit drin hätte :sunglasses:

sorce codes:

Ergebnisse:

HaWe:
ich habe einen Benchmarktest für einen ARM7 und einen ARM9 Microcomputer geschrieben, und mich würde interessieren, ob man ihn auch auf einen Due portieren kann.
Er ist teilw. sehr speicherintensiv (Kopier- und Sortier-Tests von 3 verschiedenen int array[500]), wenn das den Specher überfordert, könnte man auch die Teil-Tests weglassen. (edit - sah gerade: 96kB RAM - das reicht 100%ig !)

Mit 1500 Integerwerten kannst Du es sogar auf einen 8-Bit Controller "Arduino MEGA2560" portieren.

Native 16-Bit int Werte belegen 15002Byte = 3000 Bytes.
Umgeschrieben auf 32-Bit long Werte 1500
4 Byte =6000 Bytes
Der Atmega2560 hat 8 kB RAM und der portierte Benchmark sollte in beiden Fällen lauffähig sein:
Mit nativen 16-Bit Integer.
Und mit 32-Bit Integern, die in dem Fall auf einem 8-Bit Controller "long" heißen.

stimmt! 8)

Man kann das auch einfach System-unabhängig deklarieren:
uint8_t
uint16_t
uint32_t

Und man kann abfragen welcher Prozessor vorhanden ist:

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#elif defined(__AVR_ATmega328__) 
#elif defined(__SAM3X8E__)       //oder: (_VARIANT_ARDUINO_DUE_X_)
#endif

Oder auch:

#if defined (__AVR__)
#elif defined(__ARM__)
#endif

danke - mit so etwas hatte ich bisher noch nichts zu tun ... :o

Um das klar zu zustellen, das ist bedingte Kompilierung mit dem C-Präprozessor:

Der Code bei nichtzutreffenden Bedingungen wird gar nicht erst kompiliert. Dadurch kann man Code erstellen, der ansonsten unmöglich wäre. z.B.:

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__SAM3X8E__) 
    uint32_t array[1500];
#else
    uint16_t array[500];
#endif

Das erstellt auf dem Mega und Due ein Array mit 32-Bit Werten das 6kB belegt und auf allen anderen Prozessoren (z.B. UNO oder Leonardo) ein kleineres Arrays aus 16-Bit Werten das 1kB belegt.

ja, danke, die #ifdefs kenne und verwende ich, nur mit den Prozessorkürzeln hatte ich bislang noch nichts zu tun. Meine Projekte werden wschl aber auch eher "maßgeschneidert" bleiben - vorerst :wink:

ps - trotzdem, da ich keinen Due habe und der der einzige ARM-Arduino ist - würde mich sehr der Benchmark interessieren!
Wer also Lust und Zeit hat... 8)

Hallo,

ich habe da mal einen kurzen Blick drauf geworfen und folgendes versucht:

Quellcode für "NXT + NXC" aus dem Link oben:

//--------------------------------------------
// Mersenne Twister
//--------------------------------------------
const int N_MTW = 25;
const int M_MTW = 7;
const unsigned long A_MTW[] = {0, 0x8ebfd028};

unsigned long y_MTW[25];
int i_MTW;
bool virgin_MTW=true, new_MTW=true;   // geändert

void InitMTW() {
  i_MTW = N_MTW+1;
}

// ...
// Bis

long test_rand_MT(){
  unsigned long s;

  for(int y=0;y<5000;++y) {
     s=randM()%10001;
  }
  return s;
}

Die Matrixsache habe ich weggelassen, da kommen diverse Compilerfehler.

Dazu dieses "Hauptprogramm"

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  float s;
  
  unsigned long time0;
  unsigned long time1;
 
  time0 = micros();
  s = test_Int_Add();
  time1 = micros() - time0;
  
  Serial.print("0 integer add/subtr : ");
  Serial.println(time1);
  
  time0 = micros();
  s = test_Int_Mult();
  time1 = micros() - time0;
  
  Serial.print("1 integer multiply/division : ");
  Serial.println(time1);  
  
  time0 = micros();
  s = test_float_math();
  time1 = micros() - time0;
  
  Serial.print("2 float operations : ");
  Serial.println(time1);   
  
  time0 = micros();
  s = test_rand_MT();
  time1 = micros() - time0;
  
  Serial.print("3 Mersenne Tw. PRNG (&,^,>>,<<) : ");
  Serial.println(time1);    
  
  Serial.println();
  
  delay(5000);
}

Die Messwerte hier sind also in Microsekunden, d.h. um 1000 größer als die Vergleichswerte aus dem anderen Link.

Ergebnisse für 3 verschiedene Arduinos:

Leonardo:
0 integer add/subtr : 4
1 integer multiply/division : 4
2 float operations : 4
3 Mersenne Tw. PRNG (&,^,>>,<<) : 107400

Due:
0 integer add/subtr : 2
1 integer multiply/division : 2
2 float operations : 103800
3 Mersenne Tw. PRNG (&,^,>>,<<) : 7735

Galileo:
0 integer add/subtr : 7
1 integer multiply/division : 7
2 float operations : 20095
3 Mersenne Tw. PRNG (&,^,>>,<<) : 918

Ob die ganz kleinen Zahlen echte Messwerte sind, bezweifle ich. Möglicherweise erkennen die Compiler nicht verwendeten Code und entfernen ihn. Wahrscheinlich geben die einfach die minimale Timerauflösung an.

Ok, einen Nachschlag hab ich noch. Programm wie oben auf Arduino Due (Cortex M3 84 MHz) und mbed ST Nucleo F401 (Cortex M4 84 MHz):

2 float operations : Due = 103,8 ms ; ST = 18,176 ms (der M4 hat eine FPU)
3 Mersenne Tw. PRNG : Due = 7,735 ms; ST = 3,796 ms

hi,
danke dir - das ist ja ein ganzer Batzen! 8)
Das versuche ich gleich mal in Form zu kriegen - alles würde wahrscheinlich sofort die Tabelle sprengen :grin:

Gegen das Herausoptimieren helfen oft jede Menge volatiles, wie im nxtOSEK- oder gpp/C Code, die sind wschl sogar am besten als Arduino-Vorlage :wink:

ps,
was ist denn das hier für ein Gerät...?

Arduino Due (Cortex M3 84 MHz) und mbed ST Nucleo F401 (Cortex M4 84 MHz)

...und ist der Galileo schneller als der Due..???

edit - jetzt erstmal schlau gegoogelt - klar, Galileo, der von Intel... 8)

HaWe:
ps,
was ist denn das hier für ein Gerät...?

Das ist das Problem bei dem Vergleich. ]:smiley:

Dieses Board kostet selbst bei der nicht als Preisbrecher bekannten Firma Conrad nur 13,10 Euro (Best. Nr. 1172444 - 62).

Das mbed Projekt wird vom Prozessorhaus ARM höchst selbst betrieben:

Die Hardwareauswahl wird von den Prozessorherstellern NXP, ST und Freescale bestückt:
http://mbed.org/platforms/

Die Programmierung erfolgt online mit einer Webbasierten IDE, die Boards erscheinen als USB-Speicher am PC, übersetzte Programme kann man einfach draufkopieren. Die C++ Unterstützung ist besser als bei Arduino, es gehen auch Sachen wie std::string, usw. Alternativ kann man jeweils auch die passenden IDEs für den jeweiligen Prozessorhersteller verwenden.

Das Testprogramm war nur minimal angepasst:

#include "mbed.h"

Timer t;

Serial usb(USBTX, USBRX); 

// Hier den Benchmark Code

int main() {
    while(1) {
        float s;
        
        t.start();
        s = test_Int_Add();
        t.stop();
        printf("0 integer add/subtr : %f\r\n", t.read());
        t.reset();
      
        t.start();
        s = test_Int_Mult();
        t.stop();
        printf("1 integer multiply/division : %f\r\n", t.read());
        t.reset();
      
        t.start();
        s = test_float_math();
        t.stop();
        printf("2 float operations : %f\r\n", t.read());
        t.reset();
      
        t.start();
        s = test_rand_MT();
        t.stop();
        printf("3 Mersenne Tw. PRNG (&,^,>>,<<) : %f\r\n", t.read());
        t.reset();
    
        wait(5.0);
    }
}

das ist ja der Wahnsinn!
Leider sind die Infos etwas sehr unübersichtlich sortiert - aber da lohnt es sich wirklich mal einen Blick drauf zu werfen.
Da die Seiten so überfrachtet sind, dass ich den Wald vor Bäumen momentan nicht sehe:

  • sind die pins kompatibel zum Due ?
  • mit 5V oder auch nur 3,3V ?

(edit: Speicher habe ich gefunden: http://mbed.org/platforms/ST-Nucleo-F401RE/)

  • wie werden die beiden Cortex Prozessoren M3 und M4 verbunden? (oder sind sogar noch mehr als 2 drauf?) automatisch (d.h. man programmiert einfach drauf los, wie bei einem Mega) ? Oder muss man sich um iwas kümmern?

  • gibt es hier ein deutsches Forum, so wie dieses hier, oder kann man sogar hier direkt Fragen dazu stellen? (mit englischen Foren tue ich mich sehr schwer)

Hallo,

du hast eigentlich schon die beiden Punkte gefunden, die mir bei mbed nicht gefallen. Man sucht ziemlich viel auf dieser Webseite herum, insbesondere der Code und Forenteil sind so unübersichtlich, dass ich da nur selten reingehe.

Die IDE dagegen ist ok. Sie ist auch die hilfreichste Doku, wenn man in der Baumansicht durch die Library geht. Ansonsten die Links "Handbook" und "Cookbook" oben auf der Webseite.

Die mbed gibt es meines Wissens nach nur in 3.3 V. Manche, wie der LPC1768, haben 5V tolerante Eingänge.

Ich benutze Arduino und mbed schon eine Weile parallel. Normalerweise habe ich in jeder Größe ein Controllerboard und eines in DIL-Form für die Steckplatine.

Für 5V den Leonardo und den Micro. Für 3.3 V den Due und den mbed LPC1768. Und neuerdings als Ergänzung den Nucleo F401 und den LPC4088.

Die ST Boards können über Jumper unterschiedlich konfiguriert werden. Neben dem mbed Betrieb geht auch richtiger Programmer/Debugger Betrieb, das dann aber mit der richtigen Entwicklersoftware nicht mit der Online-IDE.

Mit dem Programmer kommt man im mbed Modus nicht in Berührung, das läuft alles intern im Board. Der Programmerteil ist über einen dieser Stege mit dem UART2 (Pins PA_2, PA_3) verbunden. Das lässt sich über einen Jumper trennen.

In diesem Detail unterscheiden sich die billigen ST-Boards von den teuereren mit NXP und Freescale. Die haben eine native USB-Verbindung vom Controller zum PC.

danke für die Info!
was ich nicht verstehe: wie wird denn der KOntakt jetzt zum PC hergestellt, wenn nicht über USB? Nackte Kabel??

Und was bedeutet online-IDE: wird die übers Web ohne Installation aufgerufen? Und die compiliert und uploaded dann automatisch?

Ist die IDE ind die API-Syntax mit Sketch vergleichbar, also ohne 1000000 verschiedene Klassen, einfach straight C, mit einfachen libs und ohne großes Projekte-Tohuwabohu (halt wie Sketch) ?

Wie schon geschrieben, erfolgt die Verbindung über USB. Nur das man bei ST halt mit dem Programmer verbunden ist, nicht mit dem eigentlichen Controller. Für die Bedienung macht das aber keinen Unterschied.

Wenn man ein Controllerboard zum ersten Mal an einen Windows-PC anschliesst, erscheint nur ein USB-Laufwerk, das "mbed","Nucleo" oder "Freedom" heißt. Windows meckert nicht über einen fehlenden Treiber, wie bei einem jungfräulichen Arduino Anwender.

Will man die serielle Verbindung in seinem Programm benutzen, braucht man dazu allerdings doch einen Treiber. Davon gibt es zwei unterschiedliche, einen von ST und einen von ARM für alle anderen.

(Hinweis: Bei einem frischen Board sollte man jetzt erstmal den jeweiligen Anweisungen zum Firmware Update folgen. Die Erfahrung zeigt, dass das oft nötig ist.)

Auf dem USB-Laufwerk liegt eine HTML-Datei. Wenn man die anklickt, öffnet der Browser die Anmeldeseite der IDE. Zu der schreibe ich jetzt nicht viel. Dazu gibt es Bilder und Videos genug.

Die Programmiersprache ist C++, kein C. Aber in vielen Fällen Arduino Sketch sehr ähnlich. Sieh dir die Beispiele an.

Appropos Beispiele: Das ist auf der Webseite sehr nützlich. Da sind überall diese grünen "Import this program" oder "Import this library" Buttons. Klickt man darauf, mach der Browser gleich ein IDE-Fenster mit dem Code auf.

Hat man ein Programm erfolgreich übersetzt, öffnet sich der Download Dialog des Browsers mit einer Datei "Programmname Boardname.bin". Die kopiert man auf das USB-Laufwerk.

Beim ST war es das schon. Das USB-Laufwerk verschwindet kurz, auf dem Board flackert eine LED, das Programm startet und das USB-Laufwerk erscheint wieder leer. Bei den anderen Modellen muss man die Reset-Taste drücken, die schauen jeweils beim Neustart nach einem neuen Programm.

Das wars schon. Mehr ist da nicht. :slight_smile:

danke für die ausführliche Info!
Ich habe zwar jetzt gerade erst einen Mega2560 bestellt, allerdings den nur als I/O-Multiplexer und i2c-Slave.

Als Master nutze ich gerade den praktischen NXT, vllt auch noch mal iwnn den EV3.
Da der EV3 aber extrem schwer mit C zu programmieren ist, halte ich schon nach einer Alternative Ausschau - dachte zuerst an Due, evtl. mal Tre, aber dein mbed sieht nach einer echten Alternative aus, v.a. auch preislich.

Wäre super-optimal, wenn sich jetzt der Speicher noch aufrüsten ließe - 256-512 MByte RAM wären optimal! 8)

HaWe:
256-512 MByte RAM wären optimal!

Das geht und ist nur knapp teurer als ein Due.

Man nimmt die existierende Hälfte vom Tre

und die TI Starterware für AM335x
http://processors.wiki.ti.com/index.php/StarterWare
Dann kann man einen Cortex A8 mit 1 GHz und 512 MB Ram als Mikrocontroller programmieren.

Traue ich dir aber nicht so direkt zu. :slight_smile:

Wird sicher auch mit dem Tre gehen. Nur bis der kommt, ist wahrscheinlich schon der Beaglebone Nachfolger mit einem der neuen A9 oder A15 basierenden Controller draußen.

Traue ich dir aber nicht so direkt zu. :slight_smile:

ich mir ehrlich gesagt auch nicht, und wenn du das gleich schon sagst...

Es dürfte nichts sein, was irgendwas mit direktem Linux-Kontakt, makefile, gdb oder Eclipse benötigt, nur was ganz simples, wie Sketch, mit ganz simpler IDE.
Das traue ich mir gerade noch zu (und davon bin ich auch geradezu begeistert :slight_smile: ).

ps, wollte ich übrigens schon lange gefragt haben...
hast du den Due-Test auch mit Sketch programmiert - oder wie und womit?