mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Arduino Benchmark auf verschiedenen MCUs


Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da ja mittlerweile verschiedene MCUs durch die Arduino IDE unterstützt 
werden, möchte ich mal wissen, wie schnell die Peripherie damit ist.

Hier mal der erste Test mit einem Arduino Uno:

digitalWrite speed benchmark
=============================
number of tries: 100000  duration [us]: 519212  ==> speed 
[megaSamples/second] : 0.19

analogRead speed benchmark
=============================
number of tries: 100000  duration [us]: 11200052  ==> speed 
[kiloSamples/second] : 8.93

Knapp 9kHz für den ADC ist fast ein wenig langsam. Jetzt bin ich mal 
gespannt, wie schnell so was auf einem STM wird.

Autor: Stefan Us (stefanus)
Datum:

Bewertung
3 lesenswert
nicht lesenswert
Wenn du die Register direkt ansprichst, geht es VIEL schneller.

Genau genommen hast du da nicht die Performance des µC getestet, sondern 
die Performance des Arduino Frameworks.

: Bearbeitet durch User
Autor: STM Apprentice (Gast)
Datum:

Bewertung
3 lesenswert
nicht lesenswert
Markus schrieb:
> Knapp 9kHz für den ADC ist fast ein wenig langsam.

Die Ergebnisse sollten einem motivieren mal ins "richtige"
Programmieren überzugehen.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Die Ergebnisse sollten einem motivieren mal ins "richtige"
>Programmieren überzugehen.

Stell Dir mal vor, wenn Du den Job seit 30 Jahren machst ( so wie ich ) 
und zig Prozessorarchitekturen hinter Dir hast wird es irgendwann mal 
langweilig und zu umständlich sich mit jeder zusätzlich hinzu kommenden 
Architektur zu befassen.
Wenn Du dann einfach nur Problem lösen willst, kommt die Zeit der 
Software Frameworks die eine platformunabhängige und einfache 
Programmierung erlauben.
Mach es einfach mal lange genug, dann wirst Du schlauer.

>Wenn du die Register direkt ansprichst, geht es VIEL schneller.
>Genau genommen hast du da nicht die Performance des µC getestet, sondern
>die Performance des Arduino Frameworks.

Weiß ich. Das war genau die Absicht: Der Test des Gesamtsystems.

Autor: DraconiX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus schrieb:
> Knapp 9kHz für den ADC ist fast ein wenig langsam. Jetzt bin ich mal
> gespannt, wie schnell so was auf einem STM wird.

Selbst 190khz beim digitalWrite ist eigentlich mehr als lächerlich, was 
macht das Framework?! Startet der für jeden Pin-Change den µC neu oder 
warum ist das so miserabel?!

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Selbst 190khz beim digitalWrite ist eigentlich mehr als lächerlich, was
>macht das Framework?! Startet der für jeden Pin-Change den µC neu oder
>warum ist das so miserabel?!
Es abstrahiert den Pin-Zugriff durch eine Pin-Nummer, damit die Software 
auf  Boards mit verschiedenen MCUs läuft. Man kann z.B. einen Arduino 
Uno mit Atmega328 und einen Arduino Due mit ARM-MCU austauschen:

https://github.com/arduino/Arduino/blob/master/har...
( Zeile 138 )

Es gibt schnellere Versionen mittels C++ Templates, aber die wurden 
leider nie in den Main-Zweig aufgenommen.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier das Ergebnis mit einem der Arduino-Frameworks auf dem Nucleo-64 ( 
STM32L476 ):

digitalWrite speed benchmark
=============================
number of tries: 100000  duration [us]: 39651  ==> speed 
[megaSamples/second] : 2.52

analogRead speed benchmark
=============================
number of tries: 100000  duration [us]: 3258145  ==> speed 
[kiloSamples/second] : 30.69

Der Pin Zugriff ist hier deutlich schneller, aber der ADC mit 
~30kSamples/s nicht so richtig überzeugend.

Autor: Jörg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Damit andere auch ihren Spaß haben können, wäre es schön, wenn Du den 
Code posten könntest.

Dann wären die Ergebnisse vergleich- und nachvollziebar.

Autor: STM Apprentice (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg schrieb:
> Dann wären die Ergebnisse vergleich- und nachvollziebar.

Wenn ich weiss dass ich beim AVR im direkten Programmieren
den Faktor 10 beim DigialWrite erreichen kann brauch ich
kein Testprogramm mehr um irgendwas nachzuvollziehen.

Your mileage may vary. Sagte schon immer der Franzose.

Autor: Markus (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
> Code posten könntest.

Bitteschön ;-)

Autor: Rudolph (Gast)
Datum:
Angehängte Dateien:

Bewertung
1 lesenswert
nicht lesenswert
Ist halt so, Arduino kostet.

Aber wie viel konkret ist nicht nur von der Plattform, sondern auch von 
der Implementierung abhängig.
Und von dem was man da gerade macht.


Das Bild ist für den Code hier:
digitalWrite(D8, LOW);
digitalWrite(D4, LOW);

Also im Grunde messe ich da wie lange es dauert einen Pin zu setzen.
Das läuft da gerade auf einem ESP8266 mit 80MHz, die 438ns sind also nur 
35 Taktzyklen was für Arduino schon am unteren Ende der Skala sein 
dürfte.

Andererseits messe ich auch das hier:
SPI.transfer(0x55);
SPI.transfer(0x55);

Damit sehe ich auf dem Scope zwischen dem Ende des ersten Transfers und 
dem Anfang des nächsten Transfers eine Lücke von 2,3µs, das sind 184 
Taktzklen für was auch immer.

Zusammen sieht das so aus:
digitalWrite(D8, LOW);
digitalWrite(D4, LOW);
SPI.transfer(0x55);
SPI.transfer(0x55);
digitalWrite(D8, HIGH);
digitalWrite(D4, HIGH);

Zwischen Low für D4 und der ersten Flanke auf SCK vergehen 1,7µs, es 
werden also 136 Taktzyklen benötigt um die Daten auf den SPI zu werfen 
und nach dem Transfer noch mal schlapp 50 Zyklen um wieder zurück zu 
kommen.
Ich würde mal vermuten, dass da noch Potential für Optimierungen ist.

Alles nicht schlimm, muss man nur mit rechnen.
Und durch verschiedene Implementierungen auch nicht unbedingt 
vergleichbar.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In Deinem Oszi Bild steht 1/dt=2.28Mhz
Das ist relativ nahe an den 2.52 MSPs aus meinem Benchmark.

Du könntest auch einfach mal den Benchmark laufen lassen.

Autor: 1234567890 (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Markus schrieb:
> tell Dir mal vor, wenn Du den Job seit 30 Jahren machst ( so wie ich )
> und zig Prozessorarchitekturen hinter Dir hast wird es irgendwann mal
> langweilig und zu umständlich sich mit jeder zusätzlich hinzu kommenden
> Architektur zu befassen.
> Wenn Du dann einfach nur Problem lösen willst, kommt die Zeit der
> Software Frameworks die eine platformunabhängige und einfache
> Programmierung erlauben.
> Mach es einfach mal lange genug, dann wirst Du schlauer.

Ja, ich finde die Frameworks auch nicht schlecht. Bei vielen einfachen 
Aufgaben kommt man so schnell zum Ziel.
Leider kommt man auch schnell an die Grenzen und kann mit Framework die 
gewünschte Performance oder den gewünschten niedrigen Energiebedarf 
nicht erreichen.

Weiterhin führen die Frameworks dazu, dass fast jeder ohne 
Expertenwissen schnell zum Ziel kommen kann. Dies wiederum führt in 
einigen Fällen zu einer schlechten Performance, da nicht nur das 
notwendige, sondern das Framework in der Software mitgeschleppt wird. 
Man sieht es bei ganz vielen Anwendungen: Ein 
Klick/Tastendruck/Tipp/Wisch und das Warten geht los. Zügige 
Datenverarbeitung, schnelle Datenanzeige und gutes Reaktionsvermögen auf 
Benutzereingaben schließen sich bei manchen System quasi gegenseitig 
aus.
Zusätzlich lassen Frameworks natürlich aufgrund ihrer einfachen 
Handhabbarkeit auch eine gewisse Betriebsblindheit und eine gewisse 
Faulheit zu. Daher sollte man wachsam bei der Benutzung solcher 
Frameworks sein um nicht nur eine Lösung, sondern auch eine gute Lösung 
zu finden.

Alles in Allem: Frameworks sind eine gute Sache, dennoch sollte man in 
manchen Fällen auf sie verzichten können. Dazu ist es leider notwendig, 
sich in verschiedene Architekturen einzuarbeiten, sofern man für 
verschiedene Architekturen Software schreibt.

Autor: Rudolph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ESP8266
digitalWrite speed benchmark
=============================
number of tries: 100000  duration [us]: 96273  ==> speed [megaSamples/second] : 1.04
  
analogRead speed benchmark
=============================

Soft WDT reset

ctx: cont 
sp: 3ffef280 end: 3ffef4c0 offset: 01b0

Tja, nun. :-)

Gibt der "Benchmark" die Zeit für Pin-Wechsel und zurück an? Also 0-1-0?
Gemessen habe ich ja nur 1-0.

Und Watchdog-Reset, tja, mehr als ein paar hundert ms sollte die loop() 
nicht laufen.
Ein freundliches "ESP.wdtDisable();" im Code hat gar nichts bewirkt.

Also weniger Durchläufe:
digitalWrite speed benchmark
=============================
number of tries: 10000  duration [us]: 9648  ==> speed [megaSamples/second] : 1.04
  
analogRead speed benchmark
=============================
number of tries: 10000  duration [us]: 1064127  ==> speed [kiloSamples/second] : 9.40

Autor: Arduino Fanboy (ufuf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rudolph schrieb:
> Ein freundliches "ESP.wdtDisable();" im Code hat gar nichts bewirkt.
Das darf dich nicht wundern!
Der WDT ist nicht abschaltbar.
Ganz so, wie es bei einem WDT auch sein sollte.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke ;-)

>Gibt der "Benchmark" die Zeit für Pin-Wechsel und zurück an? Also 0-1-0?

Eigentlich nicht, es sind 8 digitalWrite in der "unrolled loop":
https://www.mikrocontroller.net/attachment/highlight/327826

Seltsam ....

Gerade eben habe ich eine Template Library für die AVR-Arduinos 
gefunden, die ist extrem gut dokumentiert und sehr schnell: Sie erreicht 
die maximal mögliche Geschwindigkeit für AVR-Prozessoren.

https://github.com/mmarchetti/DirectIO

Leider nur für AVR, die ARMS wären schön ...

Autor: Rudolph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Arduino F. schrieb:
>> Ein freundliches "ESP.wdtDisable();" im Code hat gar nichts bewirkt.
> Das darf dich nicht wundern!
> Der WDT ist nicht abschaltbar.
> Ganz so, wie es bei einem WDT auch sein sollte.

Warum darf mich das nicht wundern wenn die Funktion genau für sowas in 
das Framework mit eingebaut wurde?

Aber egal, ich benötige die sicher nicht.

Markus schrieb:
> Eigentlich nicht, es sind 8 digitalWrite in der "unrolled loop":
> https://www.mikrocontroller.net/attachment/highlight/327826
>
> Seltsam ....

Tja, aber da glaube ich lieber meinem Oszi. :-)
Wenn das der Overhead durch die Schleife ist, dürfte das auf einem AVR 
auch noch mehr ausmachen.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus schrieb:
> Knapp 9kHz für den ADC ist fast ein wenig langsam.

Ein Blick ins Datenblatt verrät, die Wandlerfrequenz muß im Bereich 
50..200kHz liegen und eine Wandlung dauert 13 Takte.
Damit ergibt sich eine Wandlerrate von 3,8 ... 15kHz.
Der ADC-Teiler kann nur binare Schritte. Wenn also der Quarz unglücklich 
gewählt wurde und es kämen 201kHz raus, mußt Du die nächste Teilerstufe 
nehmen, d.h. 100,5kHz (Wandlerrate = 7,7kHz).
Für 15kHz bräuchtest Du einen 12,8MHz Quarz.

Autor: Arduino Fanboy (ufuf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rudolph schrieb:
> Warum darf mich das nicht wundern wenn die Funktion genau für sowas in
> das Framework mit eingebaut wurde?

Ein Blick in den Quellkot offenbart wundersames:
void EspClass::wdtDisable(void)
{
    /// Please don't stop software watchdog too long (less than 6 seconds),
    /// otherwise it will trigger hardware watchdog reset.
    system_soft_wdt_stop();
}

Du kannst mit der Funktion also nur den Software WDT abschalten.
Den Hardware WDT tangiert das nicht.

Autor: STM Apprentice (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter D. schrieb:
> Wenn also der Quarz unglücklich
> gewählt wurde und es kämen 201kHz raus, mußt Du die nächste Teilerstufe
> nehmen,

Das ist wie beim Yoghurt:

Wenn nachts um 0:00 Uhr das Verfallsdatum eintritt fängt der
sofort spontan das schimmeln an.

Autor: Chrys (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter D. schrieb:
> Ein Blick ins Datenblatt verrät, die Wandlerfrequenz muß im Bereich
> 50..200kHz liegen und eine Wandlung dauert 13 Takte.
> Damit ergibt sich eine Wandlerrate von 3,8 ... 15kHz.

Mit 15kHz kriegst du aber nicht mehr die 10bit Auflösung

Markus schrieb:
> Knapp 9kHz für den ADC ist fast ein wenig langsam

Ist in etwa die maximale Samplingrate für den ADC...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus schrieb:
> Es abstrahiert den Pin-Zugriff durch eine Pin-Nummer

Schlimmer noch, die Pinnummer einer ganz bestimmten Bauform eines ganz 
bestimmten AVR-Typs. Es ist also ein Unterschied, ob der MC im PDIP, 
TQFP oder MLF-Gehäuse ist. Mal ist PD0 Pin 2, 30 oder 26.
Wenn man dann den MC in einer echten Schaltung einbaut und aber im 
Framework irgendwelche Fantasie-Pinnummern findet, kann man sich nur 
noch die Karten legen.

: Bearbeitet durch User
Autor: Stefan Us (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beim Arduino Framework beziehen sich die Pin-Namen auf die Stiftleisten. 
Genau dafür taugt das sehr gut.

Wer kein Arduino Board verwendet, kann sich ja sein eigenes Mapping 
definieren.

Autor: Rudolph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Arduino F. schrieb:
> Ein Blick in den Quellkot offenbart wundersames:void
> EspClass::wdtDisable(void)
> {
>     /// Please don't stop software watchdog too long (less than 6
> seconds),
>     /// otherwise it will trigger hardware watchdog reset.
>     system_soft_wdt_stop();
> }
>
> Du kannst mit der Funktion also nur den Software WDT abschalten.
> Den Hardware WDT tangiert das nicht.

Na okay, auch schön, es gibt also zwei Watchdogs und wenn man den einen 
mit dieser Funktion abschaltet hat man ungefähr sechs Sekunden bis der 
andere anspringt.
Ein Aufruf mit 50.000 statt 100.000 könnte also gerade noch so drin 
sein, so zusätzlich zu dem was sonst noch in der loop() ist.

Autor: Markus (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger
>Schlimmer noch, die Pinnummer einer ganz bestimmten Bauform eines ganz
>bestimmten AVR-Typs.
Stefan Us
>>Beim Arduino Framework beziehen sich die Pin-Namen auf die Stiftleisten.
>>Genau dafür taugt das sehr gut.

Um das noch mal etwas besser zu verdeutlichen hier zwei Bilder mit dem 
Arduino Uno und dem Nucleo-64 Board.
Die Pin-Nummern bezeichnen die Nummern des Arduino-Standart Headers.
Auf dem Nucleo steht zwar D0, D1 .. usw meint aber digital Pin 0,1 ...

Autor: Markus (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Arduino Uno Pin Header.

Autor: Manfred (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus schrieb:
> Stell Dir mal vor, wenn Du den Job seit 30 Jahren machst ( so wie ich )
> und zig Prozessorarchitekturen hinter Dir hast wird es irgendwann mal
> langweilig und zu umständlich sich mit jeder zusätzlich hinzu kommenden
> Architektur zu befassen.
> Wenn Du dann einfach nur Problem lösen willst, kommt die Zeit der
> Software Frameworks die eine platformunabhängige und einfache
> Programmierung erlauben.

"seit 30 Jahren" macht den Unterschied! Zu der Zeit hatte ich den 
68HC805 im Einsatz und in Assembler Zyklen gezählt, weil ich 
Zeitprobleme hatte.

Ganz sicher hast Du über die Zeit ein Gefühl entwickelt, welche 
Geschwindigkeit wirklich notwendig ist.

Du kannst abschätzen, ob Arduino für Deine konkrete Anwendung 
ausreichend Geschwindigkeit bietet oder nicht.

Du weißt, dass Du "Fußpilzebene" könntest und hast es nicht nötig, über 
die Bastler herzuziehen oder den xxx zu verlängern, weil Du per 
Assemblercode länger auf Ereignisse warten kannst.

Jetzt erzeugst Du Benchmarks und schätzt den Gesamtaufwand ab, ob ein 
größerer µC mit Arduino oder ein kleiner in Assembler sinnvoller wäre.

Also: Gute Vorgehensweise, ich habe nichts auszusetzen :-)

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>"Fußpilzebene"

loll :-)

>Ist in etwa die maximale Samplingrate für den ADC...

Harspalterisch könnte ich mich jetzt darauf versteifen, dass der ATMEGA 
ADC auch auf 150kHz übertackted werden kann. Das funktioniert in der 
Praxis gar nicht so schlecht.
Auf was ich eher hinaus wollte war aber, dass der schnellste ADC des 
STM32L467 eigentlich 5MSPs kann ( wenn ichs in den Specs richtig 
überflogen habe ) aber im Benchmark nur 30kSps erreicht werden.
Aber vielleicht haben sie sich ja auch am Arduino-Uno grob orientiert.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.