moderne Controller werden immer schneller getaktet - nur was kommt dabei
an den IO-Pins davon an?
Beispiel: Ein 8bit-AVR braucht 375ns um in einer Schleife einen Pin high
und dann wieder low zu setzen.
Bei einem Arm-Prozessor (32bit) der angeblich viel schneller sein soll
sah ich im Netz ein Bild wo das Setzen/Rücksetzen 3.16us gedauert hat.
Das ist also Welten langsamer.
Wer nun Peripherie an IO-Pins anschließt und mit
Pinsetz-/Pinrücksetzbefehlen arbeitet wird langsamer sein als mit AVR.
Warum nur sind Arm scheinbar so langsam? Oder ist das ein Messfehler?
Sind AVR wirklich so viel schneller?
Wie sieht es mit MSP430 aus?
Matthias W. schrieb:> sah ich im Netz ein Bild wo das Setzen/Rücksetzen 3.16us gedauert hat.
Dann suche weiter nach anderen Bildern.
Oder mach dir selbst ein Bild.
Matthias W. schrieb:> Das ist also Welten langsamer.
Ja, Rückschritt statt Fortschritt!
Matthias W. schrieb:> Beispiel: Ein 8bit-AVR braucht 375ns um in einer Schleife einen Pin high> und dann wieder low zu setzen.
Bei welchem Takt? Wäre hier eine Angabe der Taktanzahl nicht
zielführender?
Grundsätzlich braucht ein AVR zum Toggeln nur einen Befehl, wenn man auf
das PIN Register schreibt. Dazu kommen 2 Takte für den Sprung der
Endlosschleife.
> Bei einem Arm-Prozessor (32bit) der angeblich viel schneller sein soll> sah ich im Netz ein Bild wo das Setzen/Rücksetzen 3.16us gedauert hat.> Das ist also Welten langsamer.
Bei ARM sieht das im Prinzip ähnlich aus. Selbst wenn man
Read-Modify-Write machen müsste, wären das ein paar Takte mehr, aber
beim vielfachen der Taktfrequenz wäre der ARM immernoch deutlich
schneller und nicht um Größenordnungen langsamer
Außerdem sagt 8 Bitter vs. 32 Bitter nichts über die Geschwindigkeit
aus, und schon gar nicht bei Pin-Toggle Aufgabenstellungen. Die 32 Bit
haben die Vorteil an ganz anderer Stelle (Arithmetik, Adressraum usw.).
Welcher ARM, bei welchem Takt? Und du hast irgendein Beispiel, irgendwo
im Netz gesehen und verallgemeinerst das jetzt?
Auf so einer Grundlage kann man nicht vernünftig diskutieren. Zeig deine
konkreten Beispiele an hand derer du deine kruden Thesen/Fragestellungen
ableitest.
Cyblord -. schrieb:> Grundsätzlich braucht ein AVR zum Toggeln nur einen Befehl, wenn man auf> das PIN Register schreibt. Dazu die Takte der Endlosschleife. Oder wenn> du einmalig setzen und löschen willst, reichen 2 Befehle, die in 2
In der Endlosschleife benötigt er 4 Takte. Das ergibt bei einem 8MHz
Takt eine Signalrate von 2MHz.
Matthias W. schrieb:> Beispiel: Ein 8bit-AVR braucht 375ns um in einer Schleife einen Pin high> und dann wieder low zu setzen.
Ohne Angabe vom Takt, welcher bei beiden gleich sein sollte für diesen
Vergleich, nützt diese Messung nichts weil nicht gleiches mit gleichem
verglichen wird.
Kann ein Softwareproblem sein. Früher als richtige Männer noch richtige
Männer waren, wurden IO_Pins direkt aka baremetal programmiert. Da
konnte man das noch in ein paar Takten erledigen.
Heutzutage muss der UserTask warten bis der Taski-scheduler ihn
ranlässt, dann checkt der MemMapper ob der User überhaupt auf dem
Mem-Bereich zugreifen darf und schliesslich muss der Treiber durch
etliche HAL's durchgreifen bis sich schlussendlich an dem Port was tut.
Da war selbst der mit 0,985248 MHz getatktete C64 mit dem BASIC-Befehl
POKE 56577,255 schneller ...
Cyblord -. schrieb:> verallgemeinerst das jetzt?
nein. Ich bin lediglich neugierig warum die einfache Aufgabe einen Pin
mal high und dann low zu setzen auf dem Arm der mehr Taktfrequenz hat
als der AVR fast Faktor 10 länger dauert. So sah es für mich aus.
Korrigiert mich wenn es nicht so ist.
Für mich zählt das was das Oszi anzeigt. Das Oszibild war klar.
Matthias W. schrieb:> Beispiel: Ein 8bit-AVR braucht 375ns um in einer Schleife einen Pin high> und dann wieder low zu setzen.>> Bei einem Arm-Prozessor (32bit) der angeblich viel schneller sein soll> sah ich im Netz ein Bild wo das Setzen/Rücksetzen 3.16us gedauert hat.
Dann wirf das Bild mal direkt in die Tonne. Bilder gibt es viele.
Siehe:
Beitrag "Re: STM32 Main loop zu langsam?"
Da schafft man schon mal mit einem eher mäßigen Programm (auf HAL-Ebene)
2 MHz, also 500ns.
Und wenn Du ein paar Beiträge weiterliest, erfährst Du, dass man auch
mit simplen GPIO-Befehlen ohne Timer auf das Vierfache kommen kann:
1
while(1){
2
LI_CH1_GPIO_Port->BS=LI_CH1_Pin;
3
LI_CH1_GPIO_Port->BR=LI_CH1_Pin;
4
}
Damit sind 8MHz bzw. 125ns auch in einer Schleife locker drin.
Also: Entsorge Dein "Bild", das ist Bullshit.
EDIT:
Aus den darunter folgenden Beiträgen geht nicht ganz klar hervor, ob der
Faktor 8 lediglich an der Optimierung lag und
1
HAL_GPIO_TogglePin(LED2_GPIO_PORT,LED2_PIN);
bereits ausreichte, um auf die 8MHz zu kommen, oder ob es die obige
Set/Reset-Schleife war.
bitwurschtler schrieb:> Heutzutage muss der UserTask warten bis der Taski-scheduler ihn> ranlässt
wenn es so ist wäre das natürlich ein unfairer Vergleich, der jedoch
dann zeigt wie viel langsamer ein Zugriff werden kann wenn man das so
nutzt.
Für die folgende Aussage möchte ich meine Hand nicht ins Feuer legen,
aber ich bin der Meinung, dass selbst mit HAL ein Toggeln in weniger als
1 us möglich ist.
Falls gewünscht kann ich es heute Abend ausprobieren.
Gruß Daniel
Daniel B. schrieb:> Für die folgende Aussage möchte ich meine Hand nicht ins Feuer legen,> aber ich bin der Meinung, dass selbst mit HAL ein Toggeln in weniger als> 1 us möglich ist.> Falls gewünscht kann ich es heute Abend ausprobieren.
Es ist gewünscht :)
Daniel B. schrieb:> Für die folgende Aussage möchte ich meine Hand nicht ins Feuer legen,> aber ich bin der Meinung, dass selbst mit HAL ein Toggeln in weniger als> 1 us möglich ist.
Glaube ich auch. Ich habe mir nochmal den Thread
https://www.mikrocontroller.net/topic/goto_post/5170022
durchgelesen. Es sieht sogar so aus, als dass der TO dort allein mit der
richtigen Optimierung auf seinem STM32F1 auf die 8 MHz gekommen ist.
Denn schließlich ist HAL_GPIO_TogglePin() ja auch nichts mehr als das:
> Falls gewünscht kann ich es heute Abend ausprobieren.
Sehr gerne! Dabei würde mich dann folgendes interessieren:
1. Toggle per HAL
2. Toggle per Bitset auf ODR-Register
3. Toggle per Set und Reset
Ich würd's ja mal mit meinem STM32F7 ausprobieren, aber mein Oszilloskop
hat nur 100Mhz Bandbreite, da wird man von den zu erwartenden 108Mhz
nicht viel sehen...
Frank M. schrieb:> Entsorge Dein "Bild", das ist Bullshit.
dieses sogenannte "Bullshit-Bild" stammt von dieser Seite:
https://www.heise.de/developer/artikel/Review-Ein-Blick-auf-den-Arduino-Zero-2749795.html
Review: Ein Blick auf den Arduino Zero
"Alle Zeros haben einen mit 48 MHz arbeitenden 32-Bit-Prozessor aus dem
Hause Atmel, der zur Beschleunigung von speicherintensiven Tasks einen
DMA-Controller (Direct Memory Access) mitbringt."
"Um die folgenden Schritte nachvollziehen zu können, ist ein Rechner mit
Windows 8 und mindestens Version 1.7.4 der Arduino-IDE nötig. Für das
Debugging kommt Atmel Studio und ein ergänzendes Plug-in des
Unternehmens Visual Micro zum Einsatz."
"Um die digitale Ausgabe zu testen, lässt sich eine weitere Version des
zuvor verwendeten Sketch nutzen:"
Es wird offenbar diese Ausgabe benutzt:
void loop() {
digitalWrite(13,LOW);
digitalWrite(13,HIGH);
}
Das sollte ja wohl nicht so sehr verkehrt sein.
"angeschlossenes Oszilloskop das in Abbildung 3 gezeigte Schirmbild."
Auf dem Bild ist klar zu sehen daß die Zeit für eine solche Schleife
3.16us dauert. Das ist nicht mein Testaufbau - sondern ein Review von
Heise. Ich hoffe doch daß diese Leute wissen was sie tun.
Dr. Sommer schrieb:> von den zu erwartenden 108Mhz nicht viel sehen
man wird wohl sehen ob das viel schneller ist als die 3.16us die Heise
hier angeblich gemessen hat - siehe das Bild.
Matthias W. schrieb:> Ich hoffe doch daß diese Leute wissen was sie tun.
Die haben einfach nur das Arduino Zeug aktiviert. Das ist nicht gerade
für seine Performance bekannt. Was eigentlich blöde ist, denn mit ein
paar kleinen Änderungen könnte das deutlich schneller sein.
Cyblord -. schrieb:> Auslachen, stehen lassen. So verfährt man mti Typen wie dir.
sachlich klingt das nicht. Es trägt auch leider nichts zur Aufklärung
bei.
Matthias W. schrieb:> Dr. Sommer schrieb:> von den zu erwartenden 108Mhz nicht viel sehen>> man wird wohl sehen ob das viel schneller ist als die 3.16us die Heise> hier angeblich gemessen hat - siehe das Bild.
Naja, ich hab damit mal ein 37Mhz Signal gemessen (kam auch aus nem ARM)
und das brauchte auch schon viel Phantasie. Das zu erwartende Ergebnis
ist den Aufwand nicht wert...
Matthias W. schrieb:> Cyblord -. schrieb:>> Auslachen, stehen lassen. So verfährt man mti Typen wie dir.>> sachlich klingt das nicht. Es trägt auch leider nichts zur Aufklärung> bei.
Nun ja, weil derart unsachlicher Fragestellung ist IMO Hopfen und Malz
verloren. Hier wird das Arduino Framework verwendet. Dessen
Geschwindigkeit auf verschiedenen Plattformen wird dann irgendwie als
Indikator für die Plattform an sich herangezogen. Von jemandem der
offensichtlich null Ahnung von der Materie hat. Was will man da sonst
sagen?
Das sind meist so "ich stelle ja nur Fragen" Typen. Aber die Fragen sind
abstrus und sinnlos und ohne jegliches Fachwissen. Jede Antwort eine
Verwschendung von Zeit und Atemluft.
Arbeite dich in die Thematik ein, mache selbst Versuche, bekomme einen
Überblick über das Thema. Dann kannst du sinnvolle Fragen stellen über
die man auch diskutieren kann.
Dr. Sommer schrieb:> Was eigentlich blöde ist, denn mit ein> paar kleinen Änderungen könnte das deutlich schneller sein.
also sollte man solche Tests anders machen.
das Ergebnis jedoch ist einfach so wie oben zu sehen. Kann das jemand
bestätigen?
im Vergleich dazu könnte man sich das Ergebnis mit einem Arduino nano 3
mit derselben IDE-Umgebung ansehen. Das wäre interessant.
Matthias W. schrieb:> Cyblord -. schrieb:>> Auslachen, stehen lassen. So verfährt man mti Typen wie dir.>> sachlich klingt das nicht. Es trägt auch leider nichts zur Aufklärung> bei.
Ich denke, es wäre auch für Dich kein Verlust an Information, wenn Du
diesen "Nutzer" ausblendetest. Von ihm kommt nichts, was sich zu lesen
lohnte.
BTDT
Cyblord -. schrieb:> Arbeite dich in die Thematik ein, mache selbst Versuche, bekomme einen> Überblick über das Thema.
ich arbeitete bereits 1982 mit Mikrocontrollern, baute damals ein
8085-System erfolgreich auf und dann ein 68000-System. Möglicherweise
warst Du da noch gar nicht auf der Welt . . .
Du kannst sicher sein daß ich einen Überblick habe . . .
Feldkurat K. schrieb:> Von ihm kommt nichts, was sich zu lesen lohnte.
Schade. Ich bin immer gerne bereit zu lernen - seit sehr vielen Jahren
ist das so. Jeder Mensch hat auch seine guten Seiten und manchmal auch
gute und wertvolle Hinweise.
Matthias W. schrieb:> Es wird offenbar diese Ausgabe benutzt:> void loop() {> digitalWrite(13,LOW);> digitalWrite(13,HIGH);> }
digitalWrite() ist eine inefffiziente Arduino-Funktion, Du vergleichst
Äpfel mit Birnen.
In diesem Fall musst Du auch auf dem AVR genau diese Loop unter Ardduino
als Benchmark ausführen.
Mach das bitte mal und berichte. Leider hast Du die Zahlen aus dem
Ursprungsbeitrag ohne Quellenangabe genannt. mittlerweile hast Du für
die STM32-Werte den Heise-Link nachgeliefert. Und wo kommen die 375ns
beim AVR her?
Matthias W. schrieb:> Es wird offenbar diese Ausgabe benutzt:> void loop() {> digitalWrite(13,LOW);> digitalWrite(13,HIGH);> }>> Das sollte ja wohl nicht so sehr verkehrt sein.
Dann vergleiche das aber bitte auch mit der Zeit, die das gleiche
Programm auf einem 8bit-AVR braucht. Die Arduino Library macht beim
digitalWrite() ein bisschen mehr, als am Pin zu wackeln.
Äpfel mit Birnen ...
Matthias W. schrieb:> Du kannst sicher sein daß ich einen Überblick habe . . .
Macht leider nicht den Eindruck.
Noch nicht mal den Artikel, auf den sich deine ganze Fragestellung
bezieht, konntest du von Anfang an, angeben.
Du rotzt hier solche Fragen ohne jeglichen Kontext rein. So kann man
natürlich auch seit 1982 arbeiten. Keine Frage. Nur macht es das besser?
>> einfach nur das Arduino Zeug aktiviert.> es klingt so als wenn dies in solchen Fällen nicht performant ist.
Es ist in keinem Fall performant. Schau dir doch einfach mal 5 Minuten
den Quellcode von digitalWrite im Arduino FW an. Für dich als Profi
sollte das sofort alle Fragen bezüglich Performance beantworten.
Aber statt eigener Recherche unter Einsatz deines enormen
jahrezentelangen Fachwissens blubbert man lieber irgendwas ins Forum.
Und als Grundlage vergleicht man direkte ASM Befehle auf dem AVR, mit
Arduino auf ARM. Glückwunsch!
Wolfgang schrieb:> Die Arduino Library macht beim> digitalWrite() ein bisschen mehr, als am Pin zu wackeln.
das mag ja so sein. Der Nutzer jedoch der diese Zeilen geschrieben hat
erwartet wohl genau das was er geschrieben hat und nicht noch 100 andere
Sachen.
Wenn man echte Performance vergleichen will kann man die
Arduino-Umgebung also schlecht verwenden. Ist es das was Du sagen willst
mit Deinem Äpfel und Birnen-Vergleich?
Warum nur verwendet dann der Redakteur von Heise der doch erfahren sein
sollte ausgerechnet die Arduino-IDE um die Performance dieses ARM-boards
zu zeigen?
Im Gegensatz zu ihm kenne ich den Overhead nicht der hinter der
Abarbeitung dieser Schleife sich verbirgt. Vermutlich lernen wir hier
gerade wieviel Overhead dahinterstecken muss.
Matthias W. schrieb:> Der Nutzer jedoch der diese Zeilen geschrieben hat> erwartet wohl genau das was er geschrieben hat und nicht noch 100 andere> Sachen.
Der Nutzer erwartet z.B. dass bei Angabe einer nicht existenten
Pin-Nummer der Controller nicht irgendwie abstürzt sondern eine halbwegs
sinnvolle Fehler-Behandlung durchgeführt wird. Außerdem erwartet er dass
aus der Pin-Nummer 17 der GPIO-Pin PA7 (beispielhaft) gefunden wird
(->Array-Zugriff), daraus die Adresse der GPIO-Register und -Bits
berechnet und diese beschrieben werden. Das sind schon einige Takte.
Matthias W. schrieb:> Warum nur verwendet dann der Redakteur von Heise der doch erfahren sein> sollte ausgerechnet die Arduino-IDE um die Performance dieses ARM-boards> zu zeigen?
Du hast ja sehr viel Vertrauen in Journalisten. Meinst du man endet als
brotloser Schreiberling wenn man Experte für Embedded-Entwicklung ist?
Matthias W. schrieb:> das mag ja so sein. Der Nutzer jedoch der diese Zeilen geschrieben hat> erwartet wohl genau das was er geschrieben hat und nicht noch 100 andere> Sachen.
Das ist halt Arduino. Man tauscht Perfomance für Komfort.
> Wenn man echte Performance vergleichen will kann man die> Arduino-Umgebung also schlecht verwenden. Ist es das was Du sagen willst> mit Deinem Äpfel und Birnen-Vergleich?
Zumindest sollte man entweder auf beiden Plattformen Bare-Metal oder auf
beiden Arduino verwenden, meinst du nicht?
> Warum nur verwendet dann der Redakteur von Heise der doch erfahren sein> sollte ausgerechnet die Arduino-IDE um die Performance dieses ARM-boards> zu zeigen?
Wahrscheinlich ein "Maker". Die Wissen doch gar nicht dass es Außerhalb
von Arduino noch eine Welt gibt. Die sind darauf hängengeblieben, aber
komplett.
> Im Gegensatz zu ihm kenne ich den Overhead nicht der hinter der> Abarbeitung dieser Schleife sich verbirgt. Vermutlich lernen wir hier> gerade wieviel Overhead dahinterstecken muss.
WIR wissen das alles schon. Du scheinst grade irgendwie aufgewacht zu
sein, und wunderst dich über Arduino.
Dr. Sommer schrieb:> Der Nutzer erwartet z.B. dass bei Angabe einer nicht existenten> Pin-Nummer der Controller nicht
diese Kontrollen werden doch wohl durch den Compiler erledigt bevor das
Programm dann überhaupt beginnt zu laufen. So viele Tests sollten ja
nicht bei so einer einfachen Endlosschleife nötig sein.
Man müsste sich den Code wohl ansehen der hinter diesem Konstrukt
steckt. Das ist dann jedoch ein anderes Thema.
Matthias W. schrieb:> diese Kontrollen werden doch wohl durch den Compiler erledigt bevor das> Programm dann überhaupt beginnt zu laufen.
Nö. Sofern die Funktion nicht geinlined wird passiert das zur Laufzeit.
Man könnte das mit templates und constexpr machen, aber dann müsste
der User vielleicht spitze Klammern in seinem Code verwenden, und das
könnte Arduino-User verschrecken.
Matthias W. schrieb:> So viele Tests sollten ja> nicht bei so einer einfachen Endlosschleife nötig sein.
Wie und wie oft die Funktion aufgerufen wird hat überhaupt keinen
Einfluss darauf, ob da eine Prüfung in der Funktion drin ist oder nicht.
Matthias W. schrieb:> Man müsste sich den Code wohl ansehen der hinter diesem Konstrukt> steckt.
Endlich mal ein sinnvoller Vorschlag
Compileroptimierung vergessen?
Auf Werte von >3us komme ich nur mit -O0 & max Debugging (-g3)
Beispiel ARM SAM D21@24MHz
-O0 -g3 -> 5,7us
-O0 -g1 -> 4,6us
-O3 -g1 -> 168ns
Alles mit HAL. Direkt auf hri-Ebene ist es ca. 30% schneller.
Auf dem SAM V71@300MHz passiert bei Toggeln des Pins gar nix mehr. Der
Io-Teiber kommt da nicht hinterher.
Ich schätze mal der Author der 3us-Messung hat einfach keine Ahnung
Cyblord -. schrieb:> Du scheinst grade irgendwie aufgewacht zu> sein, und wunderst dich über Arduino.
ich nehme die Arduino-Umgebung bewusst normalerweise nicht her weil sie
mir zu undurchsichtig ist und ich lieber mit einem brauchbaren Editor,
Make, Avrdude arbeite.
in der Tat wundert es mich wenn der Overhead so extrem groß sein soll.
Das ist schwer zu glauben. Faktor 2 könnte ich noch verstehen. Aber hier
reden wir von viel mehr ! eben das weckt auf - vielleicht auch andere !
Bei dem Anliegen geht es doch überhaupt nicht um einen objektiven
Vergleich. Der TE möchte einfach nicht, dass sein sehr einfaches
Weltbild durcheinandergebracht wird. Daher pauschaliert er auch
sämtliche ARM- und AVR-Prozessoren, ohne zu berücksichtigen, dass in der
letzten 30 Jahren(!) mittlerweile mindestens tausend unterschiedliche
ARM-basierte Prozessoren und Microcontroller eingeführt wurden.
Und natürlich muss man auch nicht berücksichtigen, dass es auch bei AVR
deutliche Leistungsunterschiede gibt oder die Ausführungsgeschwindigkeit
ganz empfindlich von der Anzahl an Waitstates des Programmspeichers und
der Nutzung und Architektur eines Caches abhängt. Was nicht sein darf,
ist eben auch nicht.
Daher nun die erfreuliche Feststellung für den TE:
Jeder beliebige AVR ist schneller als jeder beliebige andere
ARM-basierte Prozessor oder Microcontroller. Und auch in Zukunft wird
dies immer so bleiben.
Das hier ist die fragliche Stelle:
https://github.com/arduino/ArduinoCore-samd/blob/master/cores/arduino/wiring_digital.c#L74
Kurioserweise in C programmiert. Da ist deutlich mehr drin als ein
simpler Register-Zugriff, inklusive der erwähnten Prüfung. Aber kein
Test auf Buffer-Overflow. Dubios. Intelligenterweise sind auch
Fallunterscheidungen drin, die das nochmal extra langsam machen
(Pipeline-Flush).
Matthias W. schrieb:> Cyblord -. schrieb:>> verallgemeinerst das jetzt?>> nein. Ich bin lediglich neugierig warum die einfache Aufgabe einen Pin> mal high und dann low zu setzen auf dem Arm der mehr Taktfrequenz hat> als der AVR fast Faktor 10 länger dauert. So sah es für mich aus.>> Korrigiert mich wenn es nicht so ist.>> Für mich zählt das was das Oszi anzeigt. Das Oszibild war klar.
Es stellt sich auch die Frage welche Togglerate bei 3V3 single ended
physikalisch möglich ist. So ein Pin hat u.U. ne ziemliche kapazitive
Last da pumpt man für 10 MHz aka 100 ns schon einigen Strom durch. Und
irgendwann sind die Chip- PCB-Strukturen zu klein um diesen Strom
abzuhalten.
Und dann läuft beim ARM ziemlich viel über das Busprotokoll, da entsehen
auch mal schnell ein paar takte Latency oder sync-verluste im Vergleich
zum "monolithischen" AVR. Gelegentlich kommt nach dem Bus noch Bridge
und wieder ein paar Takte verzögerung:
https://m.eet.com/media/1043205/AtmelHUISoCFig5.jpg
Die Laufzeiten durch eine GPIO interconnect Matrix sind auch nicht zu
vernachlässigen. Das ist halt der Preis den man zahlen muss wenn jedes
Pin mit jedem peripheral block verschaltet werden kann.
Andreas S. schrieb:> Jeder beliebige AVR ist schneller als jeder beliebige andere> ARM-basierte Prozessor oder Microcontroller.
Nein Andreas - darum geht es mir überhaupt nicht.
Es gab/gibt die Überlegung auch einen ARM einzusetzen. Dabei sind mir
Dinge wie Zugriff auf IO-Pins wichtig. Daher schaut man auch Tests an -
so wie diesen Test. Und dann wundert man sich.
Wenn es darum ginge ARM gleich abzuschießen müsste man sich nicht die
Mühe machen zu fragen und sich ggf. auch unsachliche Antworten
anzuhören.
Dr. Sommer schrieb:> Das hier ist die fragliche Stelle:
vielen Dank. Das ist doch sehr interessant.
> Kurioserweise in C programmiert. Da ist deutlich mehr drin als ein> simpler Register-Zugriff
Es sind nicht gerade viele Zeilen. Das sollte doch normalerweise schnell
gehen? Man könnte natürlich dies auch mal für einen Test teilweise
auskommentieren.
Matthias W. schrieb:> Es gab/gibt die Überlegung auch einen ARM einzusetzen. Dabei sind mir> Dinge wie Zugriff auf IO-Pins wichtig. Daher schaut man auch Tests an -> so wie diesen Test. Und dann wundert man sich.
"Ich überlege meinen Trabi gegen einen neuen Mercedes SLS AMG
einzutauschen, und habe mir angeschaut wie schnell man damit rückwärts
fahren kann. Das kann mein Trabi schneller (vorwärts)! Jetzt frage ich
mich schon ob der Mercedes schnell genug für mich ist."
Thomas W. schrieb:> Zufällig spiele ich gerade mit dem stm32f446.
Da geht noch was. Takt auf Maximum, ART an? Roll die Schleife mal von
Hand aus
Matthias W. schrieb:> Es sind nicht gerade viele Zeilen. Das sollte doch normalerweise schnell> gehen?
Schnell ist relativ. Wenn es 10 Takte sind, ist es schon 5-10x langsamer
als der 1-2 Takt den ein optimales Programm braucht (ob AVR oder ARM).
Dr. Sommer schrieb:> Ich überlege meinen Trabi gegen einen neuen Mercedes SLS AMG> einzutauschen
nein - so ist es in meinem Fall nicht.
Es wird geschaut was für die Anwendung besser passt. Daher bin ich vom
AVR erst mal gedanklich auf einen MSP430 umgestiegen. Der Grund ist
nicht die Rechenleistung - sondern die Peripherie.
Auf die Schnelle, weil ich weg muss.
Alles komplett mit HAL und CubeMX.
einmalig toggeln:
while (1)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5);
}
mehrmals toggeln:
while (1)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5);
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5);
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5);
}
Wenn es also nur auf das Ansprechen der Pins geht, kommt man sogar mit
HAL auf 250ns.
Dr. Sommer schrieb:> Thomas W. schrieb:>> Zufällig spiele ich gerade mit dem stm32f446.> Da geht noch was. Takt auf Maximum, ART an? Roll die Schleife mal von> Hand aus
Mit Optimierung bekomme ich kein Rechteck mehr...
Thomas W. schrieb:> Mit Optimierung bekomme ich kein Rechteck mehr...
Sehr schön! Genau das meinte ich :-)
Daniel B. schrieb:> HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5);
Diese Funktion ist ziemlich dumm implementiert. Man braucht von ST ja
nicht erwarten dass die wissen wie man die eigenen Controller
programmiert...
> wo das Setzen/Rücksetzen 3.16us gedauert hat
Auf ungefähr diese Zeit komme ich beim ESP8266 mit dem Arduino Framework
bei 80Mhz Systemtakt.
Ich weiß aber auch, dass die Funktion digitalWrite() wesentlich
umfangreicher ist, als ein direkter Zugriff auf das I/O Register,
insofern überrascht mich das nicht.
Frank M. schrieb:> HAL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_PIN);> bereits ausreichte, um auf die 8MHz zu kommen, oder ob es die obige
Hmmm.
Hier einmal mit HAL
Arduino F. schrieb:> Arduino UNO, 16MHz, ATMega328P
Danke für die Messungen.
> digitalWrite(13,!digitalRead(13)); // 54 KHZ auf einem UNO
man sieht wie langsam das durch die Arduino-Befehle wird.
> out.init();> for(;;) out.toggle();// 2,667MHz auf einem UNO
das passt zu meiner Messung.
Wolfgang schrieb:> Die Arduino Library macht beim> digitalWrite() ein bisschen mehr, als am Pin zu wackeln.
Ja und was? Berechnet die nebenher Bitcoins?
So ziemlich jeder Compiler für C, Pascal, Ada... arbeitet das mit einem
sbi PORT, Pin oder einem in, xor, out in wenigen Takten ab. Mir fällt
gerade absolut nix ein, was hier an die 100 Takte (3µs x 32MHz
angenommen) rechtfertigen würde.
Karl schrieb:> Mir fällt> gerade absolut nix ein, was hier an die 100 Takte (3µs x 32MHz> angenommen) rechtfertigen würde.
Bitte erst den Thread lesen:
Dr. Sommer schrieb:> Das hier ist die fragliche Stelle:>> https://github.com/arduino/ArduinoCore-samd/blob/master/cores/arduino/wiring_digital.c#L74Dr. Sommer schrieb:> Der Nutzer erwartet z.B. dass bei Angabe einer nicht existenten> Pin-Nummer der Controller nicht irgendwie abstürzt sondern eine halbwegs> sinnvolle Fehler-Behandlung durchgeführt wird. Außerdem erwartet er dass> aus der Pin-Nummer 17 der GPIO-Pin PA7 (beispielhaft) gefunden wird> (->Array-Zugriff), daraus die Adresse der GPIO-Register und -Bits> berechnet und diese beschrieben werden. Das sind schon einige Takte.Karl schrieb:> arbeitet das mit einem> sbi PORT, Pin oder einem in, xor, out in wenigen Takten abDr. Sommer schrieb:> Nö. Sofern die Funktion nicht geinlined wird passiert das zur Laufzeit.
Allenfalls sollte Matthias W. das Thema etwas professioneller anpacken.
Ja, es gibt Controller, bei denen die IO nicht mit dem Core Schritt
haelt.
Ja, es gibt Controller, bei denen das RAM nicht mit dem Core Schritt
haelt.
Beide Informationen sind, es ist wirklich unglaublich, wir haben
wahnsinniges Glueck, im Datenblatt des jeweiligen Controllers zu finden.
Falls man die Zeit nicht hat, das soll's geben, kann man sich das
jeweilige Interface anschauen. Was ist die Logikfamilie, wie ist der
Hub. Und dann auf die maximale Geschwindigkeit schliessen. Normalerweise
ist bei LVCMOS um die 100MHz Schluss.
Es gibt allerdings auch CPLD's mit LVCMOS, die Sub 1ns Flanken
rauslassen. Da muss man sich dann auch Muehe geben.
Ob man die im Datenblatt spezifizierte Geschwindigkeit erreicht ist dann
eine andere Frage. Gibt es per ASM einen direkten Portzugriff, oder
kommt da noch eine Hardwareschicht, wie Callgate, Trapgate,
Memorymanager, oben drauf. Ist ein (virtualisierendes) Betriebssystem
per Software oben drauf. Kommt dann noch eine IO Library drauf. Die
ganze Packung kann einen Faktor hundert ausmachen.
Wir wissen leider nichts ueber die Anwendung des TO.
Karl schrieb:> Ja und was?
1. Von der Arduino Pinnummer auf Register und Maske umschlüsseln
2. evtl. vorhandene PWM abschalten.
Der Code liegt auf Github öffentlich aus, kannst dich also selber kundig
machen.
Habe im Moment nur einen STM32F767ZI (Nucleo-Board) zur Verfügung.
1
while(1)
2
{
3
GPIOC->BSRR=(1<<8);
4
delayXX();
5
GPIOC->BSRR=(1<<(8+16));
6
delayXX();
7
}
Ohne Delays mit dem Oszi (Leihgerät TEK2024C) für mich nicht mehr
messbar ( siehe NoDelay Pic).
Mit einem Delay (1 NOP), erahnbar, mit Delay (2 NOPs), eine
erkennbare Kurve mit ca. 8.6Mhz
Gehe ich recht in der Annahme, dass hier schlicht und einfach die
GPIO HW nicht mehr hinterherkommt mit rauf-und-runter ?
Daniel B. schrieb:> Gehe ich recht in der Annahme, dass hier schlicht und einfach die> GPIO HW nicht mehr hinterherkommt mit rauf-und-runter ?
Das Datasheet sagt was von bis zu 180 MHz, siehe Anhang - man beachte
die markierten Voraussetzungen.
Daniel B. schrieb:> Gehe ich recht in der Annahme, dass hier schlicht und einfach die> GPIO HW nicht mehr hinterherkommt mit rauf-und-runter ?
Die Last durch Deinen Tastkopf (1:1?) oder durch die
Bandbreite(nbegrenzung) Deiner Oszis kann auch solche Bilder erzeugen.
Daniel B. schrieb:> Gehe ich recht in der Annahme, dass hier schlicht und einfach die> GPIO HW nicht mehr hinterherkommt mit rauf-und-runter ?
Kann, kann aber auch an mangelnder Bandbreite Deines Messgerätes liegen.
Zwölf M. schrieb:> Ja, es gibt Controller, bei denen die IO nicht mit dem Core Schritt> haelt.> Ja, es gibt Controller, bei denen das RAM nicht mit dem Core Schritt> haelt.
Danke !
ja - ich bin wie viele andere kein profunder Insider aller uCs dieser
Welt. ARM ist für mich Neuland. Daher weiß ich nicht ob und welchen
Einfluss diese Punkte in der Praxis beim ARM haben - falls dies so sein
sollte.
> Beide Informationen sind im Datenblatt zu finden.
Datenblätter wie AVR oder MSP können 600 Seiten umfassen. Ja - ich gebe
zu nicht Datenblätter von ARM angesehen zu haben. Das kostet eine Menge
Zeit.
> Was ist die Logikfamilie, wie ist der> Hub. Und dann auf die maximale Geschwindigkeit schliessen. Normalerweise> ist bei LVCMOS um die 100MHz Schluss.
ja. daran liegt das obige Problem jedoch nicht. Die Pins schalten sicher
alle schnell genug - egal ob AVR, MSP oder ARM. Daran liegt die große
Verzögerung nicht. Warum soll ARM langsamer sein wenn die Si-Technologie
wohl dieselbe ist?
> Ob man die im Datenblatt spezifizierte Geschwindigkeit erreicht ist dann> eine andere Frage. Gibt es per ASM einen direkten Portzugriff, oder> kommt da noch eine Hardwareschicht, wie Callgate, Trapgate,> Memorymanager, oben drauf. Ist ein (virtualisierendes) Betriebssystem> per Software oben drauf. Kommt dann noch eine IO Library drauf. Die> ganze Packung kann einen Faktor hundert ausmachen.
dies ist wichtig wenn man entscheidet welche CPU man mit welchen Tools
wie verwendet. Die meisten dieser Bremser nutze ich nicht.
Nun weiß ich daß ARM Pins grundsätzlich recht schnell schalten kann und
daß die Arduino-Umgebung stark verlangsamen kann.
Vielen Dank für die Beiträge.
>> Die Arduino Library macht beim>> digitalWrite() ein bisschen mehr, als am Pin zu wackeln.> Ja und was?
Habe ich etwas weiter oben geschrieben - mit Quelltext.
Wie gesagt, Leihgerät von einem Freund, reicht mir um zu sehen,
ob sich etwas auf den SPI / I2C Pins etwas tut, und was auf dem
DAC rauskommt.
TEK 2024C 4 x 200Mhz mit Standardtastköpfen 10:1.
@Matthias W: Ist eigentlich egal, ob Du die Arduino Umgebung oder
HAL Umgebung oder etwas selber geschriebenes, sobald Du ein paar
Subroutinen dazwischen hast, bricht die Geschwindigkeit massiv ein.
So meine Erfahrung, ohne jetzt alles analysiert zu haben.
Dr. Sommer schrieb:> Dr. Sommer schrieb:>> Das hier ist die fragliche Stelle:> https://github.com/arduino/ArduinoCore-samd/blob/m...
Und? Da steh genau nichts, was derart viele Takte erfordert.
> Dr. Sommer schrieb:>> Der Nutzer erwartet z.B. dass bei Angabe einer nicht existenten>> Pin-Nummer der Controller nicht irgendwie abstürzt sondern eine halbwegs>> sinnvolle Fehler-Behandlung durchgeführt wird. Außerdem erwartet er dass>> aus der Pin-Nummer 17 der GPIO-Pin PA7 (beispielhaft) gefunden wird>> (->Array-Zugriff), daraus die Adresse der GPIO-Register und -Bits>> berechnet und diese beschrieben werden. Das sind schon einige Takte.
Ähm sorry, das macht der Compiler alles vorher und ganz gewiss nicht zur
Programmlaufzeit. Das wäre ja reichlich bescheuert.
> Dr. Sommer schrieb:>> Nö. Sofern die Funktion nicht geinlined wird passiert das zur Laufzeit.
Häh? Läuft da Python drauf oder was? Da wird ein Maschinencode generiert
und der wird genau so in wenigen Takten ausgeführt.
Dr. Sommer schrieb:> Das Datasheet sagt was von bis zu 180 MHz, siehe Anhang - man beachte> die markierten Voraussetzungen.
Cool, schon wieder was gelernt :-) Bringt aber auf die Schnelle in
meinem Bespiel nichts. Habe mal:
1
....
2
HAL_Init();
3
SystemClock_Config();
4
GPIO_Init();
5
HAL_EnableCompensationCell();
eingebaut.
Weiss aber nicht, ob das so riecht, ändert auf jeden Fall an
dem Ergebnis nichts.
Karl schrieb:> Und? Da steh genau nichts, was derart viele Takte erfordert.
Dann sind's wohl Gespenster.
Karl schrieb:> Ähm sorry, das macht der Compiler alles vorher und ganz gewiss nicht zur> Programmlaufzeit.
Ich wiederhole es nochmal: Das geht nur, wenn die Funktion geinlined
wird. Und das passiert anscheinend nicht.
Karl schrieb:> Das wäre ja reichlich bescheuert.
Ist halt Arduino.
Karl schrieb:> Da wird ein Maschinencode generiert> und der wird genau so in wenigen Takten ausgeführt.
Der Maschinencode der digitalWrite-Funktion muss aber die erforderlichen
Berechnungen durchführen. Dieser Code hat keine Ahnung mit welchen
Argumenten er wo im Code aufgerufen wird.
Karl schrieb:> Ähm sorry, das macht der Compiler alles vorher und ganz gewiss nicht zur> Programmlaufzeit. Das wäre ja reichlich bescheuert.
Gähn...
Die Arduino Pin Nummern können als Variable übergeben werden.
Z.B. können sie in einem Array liegen.
Damit MUSS das zur Laufzeit aufgeschlüsselt werden.
1. Es zwingt dich ja keiner diese Funktionen zu nutzen.
2. Meistens ist das völlig egal, wie lange die Funktionen brauchen. Die
Zeit wird woanders verwartet, oder verpollt.
Daniel B. schrieb:> TEK 2024C 4 x 200Mhz mit Standardtastköpfen 10:1.
Dann wird es mit 100 MHz und Rechteck nichts. Neben der 100 MHz
Grundwelle braucht das Rechteck auch 300, 500 usw Mhz. Da aber macht das
200 MHz Scope die Graetsche.
Boah Leute, lernt doch mal mit den Chips richtig umzugehen:
ldr R0, =(GPIOA_BASE+GPIO_BSRR)
ldr R1, =0x00000001
ldr R2, =0x00010000
Lop:
str R1, [R0] // Pin au 0 setzen
str R2, [R0] // Pin auf 1 setzen
b Lop
Gibt an zwei von drei Takten einen Flankenwechsel…
Abhängig vm Prozessortakt könnte es sein, dass die I/O-Pins nicht mehr
mitkommen.
Uwe B. schrieb:> Daniel B. schrieb:>> TEK 2024C 4 x 200Mhz mit Standardtastköpfen 10:1.>> Dann wird es mit 100 MHz und Rechteck nichts. Neben der 100 MHz> Grundwelle braucht das Rechteck auch 300, 500 usw Mhz. Da aber macht das> 200 MHz Scope die Graetsche.
Jup, und man schaue sich mal an, welchen Widerstand ein 200 MHz Tastkopf
bei 100 MHz darstellt. Das ist nicht mehr gar so hochohmig wie man es
gerne hätte.
Guido Körber schrieb:> Boah Leute, lernt doch mal mit den Chips richtig umzugehen:
So weit waren wir schon längst. Durch Ausrollen der Schleife wird's noch
besser. Das geht übrigens in C genauso gut. Viel interessanter ist die
Konfiguration des Takts und die Geschwindigkeit vom Flash und
eventueller Caches (ART, ITCM, L1).
ich finde diese Diskussionen um das Pin Wackeln sehr müssig. Wenn es
schnell gehen soll bekommt man es hin, auch mit Arduino oder HAL oder
anderen Libs. Mit den Libs kann man immer noch den Pin einfach
initialisieren und für den schnellen Zugriff geht man an der Lib mit
direkten Registerzugriffen vorbei. In C geht das mit #defines und inline
Code immer noch einigermassen elegant, ein bisschen muss man dem
Perfomancegott halt an Sicherheit opfern.
Nur warum will man beim ARM überhaupt noch Pins schnell toggeln? Es wird
z.B. noch gemacht für Grafikdisplays (und da nutzt man eben die
genannten Möglichkeiten), aber hier gibt es in den ARM Familien viel
bessere Controller mit der passenden HW Unterstützung, FSMC bei den
STM32 z.B. oder TFT Controller für komplettes HSync/VSync Timing.
Es gibt Controller mit Ethernet HW, da braucht man nur einen
Speicherblock vorzubereiten und den Empfang scharfzuschalten. Die HW
füllt den, löst einen Int aus und füllt den nächsten Block. Damit hat
man sehr schnelle Kommunikation mit geringen Latenzen, mit welchem AVR
geht das?
Dann die vielen Möglichkeiten mit DMA, auch damit kann man Bitmuster
rasend schnell auf Ports ausgeben. Andere Controller (NXP) mit SCT,
einer State Machine in HW die auf verschiedene Events reagiert. Damit
bekommt man z.B. Timings für die beliebten WS28xx LED hin mit nahezu 0
Prozessorlast. Oder robuste Steuerung für BLDC die eben in HW läuft.
Viele schnellere SPI, QSPI, CAN, I2C und dazu viel Speicher und DMA.
usw. usw.
Und dann die Prozessorarchitektur danach zu bewerten wie schnell man
einen Pin wackeln kann? Echt albern.
Matthias W. schrieb:> Frank M. schrieb:>> Und wo kommen die 375ns beim AVR her?>> das ist ein Arduino nano3 mit 16MHz.
Ja, aber nicht mit der Arduino-IDE compiliert, sondern in Assembler.
Wie Arduino Fanboy oben dokumentiert hast, kommst Du mit der Arduino-IDE
unter der Verwendung von digitalWrite() gerade mal in den zweistelligen
kHz-Bereich auf einem AVR.
Mit einfachen Register-Zugriffen (in C) sind wir dann beim STM32 im
zweistelligen ns-Bereich, wo der AVR noch nichtmals in Assembler
hinkommt.
Damit kann man nun endlich die Birnen mit den Birnen (Arduino +
digitalWrite) und die Äpfel mit den Äpfeln (optimiertes C) vergleichen.
Und schon sieht der AVR richtig alt aus.
Johannes S. schrieb:> Und dann die Prozessorarchitektur danach zu bewerten wie schnell man> einen Pin wackeln kann? Echt albern.
so albern ist das auch nicht. Es gibt schon Anwendungen wo man so etwas
ggf. brauchen kann.
es könnte sein daß man ein batteriegepuffertes RAM extern anschließen
will. Oder ein schnelles MRAM mit parallelem Zugriff. Dabei ist es dann
schon ein Unterschied ob eine Speicherzelle 3us oder 300ns braucht.
Falls so etwas mit DMA geht kann man es natürlich auch damit machen. Man
muss halt an den Speicher Adressen und Daten anlegen.
Bei den 8051 bzw. 8085 war das auch nicht anders. Bei bestimmten AVR
kann man memory mapped kleinere Speicher betreiben. Wenn die Speicher
größer sind wird es Krampf.
Es macht schon Sinn sich klarzumachen was geht und was eher nicht. Ob
man es dann nutzt ist eine andere Frage.
Viele Funktionen sind heute on chip. Manche aber nicht so gut wie man es
sich wünscht. Z.B. sind DACs mit mehr als 12bit auf Controllern eher
unüblich. Da muss man dann überlegen was man wie extern anschließt. SPI
geht zwar aber taktet deutlich schneller und kann bei jedem
Flankenwechsel Störungen verursachen die ggf. dann im Ausgang zu sehen
sind. Wenn ein LSB nur ein paar uV groß ist und der Spannungshub klein
wird das problematischer als wenn man 5V oder 10V Hub hat so wie es
früher bei DACs mal war. Über manches kann man nachdenken . . .
Wie man es dann realisiert ist eine andere Frage.
Matthias W. schrieb:> es könnte sein daß man ein batteriegepuffertes RAM extern anschließen> will. Oder ein schnelles MRAM mit parallelem Zugriff.
Und warum sollte man dafür nicht die auf ARM's vorhandenen
Speichercontroller (FSMC und FMC bei STM32) nutzen?
Dr. Sommer schrieb:> Matthias W. schrieb:>> es könnte sein daß man ein batteriegepuffertes RAM extern anschließen>> will. Oder ein schnelles MRAM mit parallelem Zugriff.>> Und warum sollte man dafür nicht die auf ARM's vorhandenen> Speichercontroller (FSMC und FMC bei STM32) nutzen?
Gabs 1982 noch nicht. Er macht seit dem alles über Pin Wackeln.
Google und PDF Datenblätter gabs damals übrigens auch noch nicht, darum
nutzt er es nicht.
Matthias W. schrieb:> Oder ein schnelles MRAM mit parallelem Zugriff. Dabei ist es dann> schon ein Unterschied ob eine Speicherzelle 3us oder 300ns braucht.
auch dafür gibt es Mitglieder in den ARM Familien da besonders fix
können, ext. Speicher ist ein gutes Argument. Vor allem weil die
Cortex-M auch den grossen Adressraum haben um grossen Speicher
(non-paged) unterzubringen...
Matthias W. schrieb:> Viele Funktionen sind heute on chip. Manche aber nicht so gut wie man es> sich wünscht. Z.B. sind DACs mit mehr als 12bit auf Controllern eher> unüblich.
ja, ist richtig, die kleinen Strukturen auf den Chips sind nicht
analogfreundlich. SPI ist da aber absolut üblich und auch hier würde das
gut mit DMA oder dem FSMC von STM gut gehen. Für die Ausgabe auf einen
DAC möchte man vielleicht auch einen konstanten Takt haben, da ist eine
Schleife in SW die ständig durch Interrupts gestört wird auch nicht so
toll.
Matthias W. schrieb:> Frank M. schrieb:>> Ja, aber nicht mit der Arduino-IDE compiliert, sondern in Assembler.>> nein - in C !
Okay, geschenkt. Pin-Wackeln macht der gcc wie ein
Assembler-Programmierer.
Hauptsache, Du vergleichst zukünftig nicht mehr ganz allgemein die
Performance von irgendwelchen Arduino-Programmen mit C-Programmen. Darum
ging es mir.
Arduino F. schrieb:> 2. Meistens ist das völlig egal, wie lange die Funktionen brauchen. Die> Zeit wird woanders verwartet, oder verpollt.
Bei Arduino: Bestimmt.
Bei einem richtigen Compiler kann man halt in der Zeit andere Sachen
machen.
Karl schrieb:> Bei einem richtigen Compiler kann man halt in der Zeit andere Sachen> machen.
Arduino verwendet den G++, den C++ Compiler der GCC. Ist das kein
richtiger Compiler? Wenn nein, was ist einer?
Dr. Sommer schrieb:> Arduino verwendet den G++, den C++ Compiler der GCC. Ist das kein> richtiger Compiler? Wenn nein, was ist einer?
Ach, das verstehst du nicht...
Er möchte gerne schimpfen, und hat jetzt was gefunden.
Frank M. schrieb:> von irgendwelchen Arduino-Programmen mit C-Programmen. Darum> ging es mir.
die Arduino-Programme sind ja auch C bzw. C++.
Nur daß ich eben nur 2 Zeilen C in der Schleife nutzte und die
Arduino-Umgebung halt viel mehr Code-Zeilen was die wenigsten wohl
wissen.
Johannes S. schrieb:> SPI ist da aber absolut üblich
üblich schon - aber vielleicht nicht immer so glücklich, denn jeder Takt
der da ans DAC-chip geführt wird - und bei SPI sind es 8-16x so viele
oder noch mehr Takte wird eine Störung auf der GND-Leitung verursacht.
Bei ein paar uV für das LSB kann man sich denken wie störbehaftet dann
das Ausgangssignal eines 16bit DAC werden kann.
Matthias W. schrieb:> Wolfgang schrieb:>> Die Arduino Library macht beim>> digitalWrite() ein bisschen mehr, als am Pin zu wackeln.>> das mag ja so sein. Der Nutzer jedoch der diese Zeilen geschrieben hat> erwartet wohl genau das was er geschrieben hat und nicht noch 100 andere> Sachen.
Dann muss er direkt den Prozessor programmieren und nicht blind
irgendwelche Funktionen aufrufen, die sonstwelche Nebenjobs erledigen.
Es steht doch jedem frei, einen Arduino ohne Weichspülfunktionen zu
programmieren. Die Bibliotheken sind auf schnelle Erfolgserlebnisse und
nicht auf Performance getrimmt.
Den 8bit-AVR hat er doch anscheinend auch direkt programmiert.
TM F. schrieb:> In der Endlosschleife benötigt er 4 Takte.
Dann hat die Ausgabe aber ein ziemlich häßlichen Duty von 1:3. Das zählt
normalerweise nicht wirklich. Realistisch muss man für die meisten
praktisch relevanten Aufgaben deshalb 6 Takte ansetzen. Nur dann kann
man ein Duty von 1:1 erreichen.
Aber: Wer würde das schon mit einer Busy-Loop lösen wollen, wenn es
Sachen wie SPI, UART(im SPI-Mode) und Timer gibt, die allesamt in der
Lage sind, 1/2 Systemtakt mit Duty 1:1 auszugeben, ohne die MCU damit
behelligen zu müssen...
Die MCU ist viel intelligenter als diese Peripherie und sollte
freigehalten werden, um komplexere Aufgaben zu lösen, als stupide Takte
auszugeben.
Wolfgang schrieb:> Dann muss er direkt den Prozessor programmieren
das mache ich die ganze Zeit (mit C eben, früher AVR-Assembler) und
meide solche Tools wie die Arduino-Umgebung wo ich kann.
Es war dieser Redakteur der diesen Benchmark eben mit dieser Umgebung
betrieb - bitte nicht vergessen. Nur so kamen wir nun dahinter was sich
an zeitlichem Overhead hier offenbar verbirgt.
Johannes S. schrieb:> Für die Ausgabe auf einen> DAC möchte man vielleicht auch einen konstanten Takt haben, da ist eine> Schleife in SW die ständig durch Interrupts gestört wird auch nicht so> toll.
ja Johannes. Gut wenn man ggf. genügend SPI-Schnittstellen hat. Oder man
muss diese umschalten. Dabei muss man ggf. aber sehr aufpassen wenn die
SPI-Slaves unterschiedliche Einstellungen benötigen. Interrupts sollten
auch da ggf. nicht dazwischenfunken.
Matthias W. schrieb:> Gut wenn man ggf. genügend SPI-Schnittstellen hat.
und auch da hat man reichlich Auswahl, moderne LPC54xxx mit bis zu 10,
selbst die kleinen LPC8xx haben 2. Bei STM findet man auch reichlich mit
2..6 SPI.
> Interrupts sollten> auch da ggf. nicht dazwischenfunken.
dann nimmt man MCUs mit DMA die auch SPI als Ziel kennen.
Matthias W. schrieb:> Es war dieser Redakteur der diesen Benchmark eben mit dieser Umgebung> betrieb - bitte nicht vergessen.
häufig wird bei dem Wunsch das Andenken an diesen Redakteur nicht zu
vergessen, die frühere soziale Missachtung des Redakteurs vertuscht:
Matthias W. schrieb:> ich arbeitete bereits 1982 mit Mikrocontrollern
..
> Du kannst sicher sein daß ich einen Überblick habe . . .Matthias W. schrieb:> Für mich zählt das was das Oszi anzeigt. Das Oszibild war klar.Matthias W. schrieb:> sah ich im Netz ein Bild wo das Setzen/Rücksetzen 3.16us gedauert hat.
wenn Matthias W. schon früher darüber informiert gewesen wäre, dass es
sich um den Überblick, Oszibild, Benchmark des Redakteurs gehandelt hat,
dann käme der Wunsch vermutlich aufrichtiger rüber.
Matthias W. schrieb:> Nur so kamen wir nun dahinter was sich> an zeitlichem Overhead hier offenbar verbirgt.
wenn keiner von euch die Möglichkeit hat hinter einen zeitlichen
Overhead zu kommen der sich "offenbar" 'verbirgt, dann wird das
natürlich kompliziert.
Ähnlich wie bei dem Wusch das Gedenken an den Redakteur nicht zu
vergessen könntet ihr versuchen euch erst die einzelnen Punkte
verständlich zu machen:
- wie habt ihr das offenbare verbergen mitbekommen?
- konntet ihr nicht den Redakteur fragen ob ein Framework u.U. etwas mit
(zeitlichem) Overhead zu tun haben könnte?
kurz: wenn ihr euch etwas sortieren könntet und versucht
"ich"/"wir"/"Redakteur" als unterschiedliche Menschen(gruppen) zu
verstehen, dann könnte das u.U. einige Missverständnisse aufklären.
Matthias W. schrieb:> Nur so kamen wir nun dahinter was sich> an zeitlichem Overhead hier offenbar verbirgt
Warum redest du ständig in der Mehrzahl von dir?
-Nucleo-Board mit STM32F103
-konfiguriert mit CubeMX
-gemessen mit Analog Discovrey 2, welches ganz schon an seine Grenzen
kam
-geändert wurde jeweils nur der Code in der while-Schleife
57 ns
while (1) {
GPIOC->BSRR = (1<<5);
GPIOC->BRR = (1<<5);
}
57 ns
while (1) {
GPIOC->BSRR = GPIO_PIN_5;
GPIOC->BRR = GPIO_PIN_5;
}
70 ns
while (1) {
GPIOC->BSRR = (1<<5);
GPIOC->BSRR = (1<<21);
}
125 ns
while (1) {
GPIOC->BSRR |= (1<<5);
GPIOC->BRR |= (1<<5);
}
140 ns
while (1) {
GPIOC->ODR = (1<<5);
GPIOC->ODR &= ~(1<<5);
}
220 ns
while (1) {
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
}
360 ns
while (1) {
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5);
}
High-Low mehrmals in einer while-Schleife
while (1) {
GPIOC->BSRR = (1<<5);
GPIOC->BRR = (1<<5);
GPIOC->BSRR = (1<<5);
GPIOC->BRR = (1<<5);
GPIOC->BSRR = (1<<5);
GPIOC->BRR = (1<<5);
}
Wenn er mal in Fahrt gekommen ist, dann geht das High-Low-Ziehen der
Pins anscheinend auch noch wesentlich schneller :-)
Weil ich gerade so am Messen war, hier noch ein Atmega168PA mit 16MHz an
5,1V. Schlägt sich nicht schlecht, der Kleine.
125ns
while (1) {
PORTD |= (1<<2);
PORTD &= ~(1<<2);
}
Über Sinn- oder Unsinn des Ganzen kann man natürlich streiten. Genauso
über meine Fähigkeiten und die meiner Messgeräte.
Natürlich gibt es noch andere und je nachdem auch sinnvollere
Möglichkeiten einen Pin zu toggeln.
Hiermit will ich auch keine hochqualitativen Aussagen machen.
Ich fand es einfach gerade interessant und vielleicht hilft es
irgendjemand irgendwann.
Gruß Daniel
Daniel B. schrieb:> Wenn er mal in Fahrt gekommen ist, dann geht das High-Low-Ziehen der> Pins anscheinend auch noch wesentlich schneller :-)
Der Sprung der Schleife ist halt "langsam". Deine Ergebnisse sind etwas
komisch, hast du die Compiler Optimierung an?
Dr. Sommer schrieb:> hast du die Compiler Optimierung an?
Gute Frage, ich habe keine Ahnung wo ich das prüfen, oder verändern
kann.
Ich arbeite mit der System Workbench for STM32.
Wenn du mir helfen könntest diese Einstellung zu finden, kann ich dir
mehr sagen.
Optimierungslevel -O2 ist eingestellt.
Soweit ich es mit meinem Oszi beurteilen kann, liegen wir jetzt bei ca.
30ns.
Und der Sprung in die while-Schleife ist jetzt wesentlich kürzer.
while (1) {
GPIOC->BSRR = (1<<5);
GPIOC->BRR = (1<<5);
GPIOC->BSRR = (1<<5);
GPIOC->BRR = (1<<5);
GPIOC->BSRR = (1<<5);
GPIOC->BRR = (1<<5);
}
Johannes S. schrieb:> Und dann die Prozessorarchitektur danach zu bewerten wie schnell man> einen Pin wackeln kann? Echt albern.
Ja, sehe ich auch so. Das ist etwa so, wie die Performance von zwei
Pogrammiersprachen zu vergleichen, indem man in beiden ein Programm
schreibt, das in einer Schleife hundert Million mal zwei Zahlen addiert
und schaut, welches schneller fertig ist.
Hier noch ein Link, der ganz gut zu beschrieben scheint, warum
digitalWrite() im Vergleich zu direktem Pinwackeln so langsam ist:
https://www.peterbeard.co/blog/post/why-is-arduino-digitalwrite-so-slow/