Forum: Mikrocontroller und Digitale Elektronik Geschwindigkeit IO-Zugriff


von Matthias W. (matt007)


Lesenswert?

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?

von Uhrmacher (Gast)


Lesenswert?

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!

von Cyblord -. (cyblord)


Lesenswert?

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.

: Bearbeitet durch User
von TM F. (p_richner)


Lesenswert?

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.

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

Mithilfe der Timer-Module kann man auf (fast?) allen ARM's einen Takt 
ausgeben mit dem man einen AVR (z.T. um ein Vielfaches) übertakten 
könnte.

von Matthias W. (matt007)


Lesenswert?

Uhrmacher schrieb:
> mach dir selbst ein Bild.

ich habe selbst noch keinen Arm und keine vergleichbare Umgebung zum AVR 
mit Make, Avrdude, Gcc.

von bitwurschtler (Gast)


Lesenswert?

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 ...

von Matthias W. (matt007)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

: Bearbeitet durch Moderator
von Matthias W. (matt007)


Lesenswert?

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.

von Daniel B. (daniel_3d)


Lesenswert?

Also ich kann beim z.B. STM32F103... ohne Probleme einen Pin im 
ns-Bereich toggeln.

Ich kann dir davon auch ein Bild machen :-)

Gruß

Daniel

von Daniel B. (daniel_3d)


Lesenswert?

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

von Matthias W. (matt007)


Lesenswert?

Daniel B. schrieb:
> auch ein Bild machen :-)

Danke Daniel !

von Cyblord -. (cyblord)


Lesenswert?

Matthias W. schrieb:
> Für mich zählt das was das Oszi anzeigt. Das Oszibild war klar

Auslachen, stehen lassen. So verfährt man mti Typen wie dir.

von Karl (Gast)


Lesenswert?

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 :)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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:
1
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
2
{
3
  /* Check the parameters */
4
  assert_param(IS_GPIO_PIN(GPIO_Pin));
5
6
  GPIOx->ODR ^= GPIO_Pin;
7
}

> 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

von Dr. Sommer (Gast)


Lesenswert?

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...

von Matthias W. (matt007)


Angehängte Dateien:

Lesenswert?

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.

von Matthias W. (matt007)


Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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.

von Matthias W. (matt007)


Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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...

von Cyblord -. (cyblord)


Lesenswert?

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.

von Matthias W. (matt007)


Lesenswert?

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.

von Feldkurat K. (feldkurat)


Lesenswert?

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

: Bearbeitet durch User
von Matthias W. (matt007)


Lesenswert?

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 . . .

von Matthias W. (matt007)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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?

von Wolfgang (Gast)


Lesenswert?

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 ...

von Matthias W. (matt007)


Lesenswert?

Dr. Sommer schrieb:
> einfach nur das Arduino Zeug aktiviert.

es klingt so als wenn dies in solchen Fällen nicht performant ist.

von Cyblord -. (cyblord)


Lesenswert?

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!

: Bearbeitet durch User
von Matthias W. (matt007)


Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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?

von Cyblord -. (cyblord)


Lesenswert?

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.

von Matthias W. (matt007)


Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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

von Fabian F. (fabian_f55)


Angehängte Dateien:

Lesenswert?

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

: Bearbeitet durch User
von Matthias W. (matt007)


Lesenswert?

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 !

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

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.

von Matthias W. (matt007)


Lesenswert?

Fabian F. schrieb:
> Compileroptimierung vergessen?

Vielen Dank für Deine Messung Fabian.

von Dr. Sommer (Gast)


Lesenswert?

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).

von bitwurschtler (Gast)


Lesenswert?

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.

von Matthias W. (matt007)


Lesenswert?

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.

von Matthias W. (matt007)


Lesenswert?

Andreas S. schrieb:
> Bei dem Anliegen geht es doch überhaupt nicht um einen objektiven
> Vergleich.

doch Andreas - genau darum geht es mir.

von Thomas W. (ratos)


Angehängte Dateien:

Lesenswert?

Zufällig spiele ich gerade mit dem stm32f446.
1
while(1){
2
    GPIOB->BSRRL=GPIO_Pin_7;
3
    GPIOB->BSRRH=GPIO_Pin_7;
4
}

von Matthias W. (matt007)


Lesenswert?

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.

von Matthias W. (matt007)


Lesenswert?

Thomas W. schrieb:
> while(1){
>     GPIOB->BSRRL=GPIO_Pin_7;
>     GPIOB->BSRRH=GPIO_Pin_7;
> }

Danke Thomas. Weniger als 70ns also. Das ist ok.

von Dr. Sommer (Gast)


Lesenswert?

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).

von Matthias W. (matt007)


Lesenswert?

Frank M. schrieb:
> Und wo kommen die 375ns
> beim AVR her?

das ist ein Arduino nano3 mit 16MHz.

von Matthias W. (matt007)


Lesenswert?

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.

von Daniel B. (daniel_3d)


Angehängte Dateien:

Lesenswert?

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.

: Bearbeitet durch User
von Thomas W. (ratos)


Angehängte Dateien:

Lesenswert?

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...

von Dr. Sommer (Gast)


Lesenswert?

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...

von Daniel B. (daniel_3d)


Angehängte Dateien:

Lesenswert?

while (1)
  {
    GPIOC->BSRR |= (1<<5);
    GPIOC->BRR |= (1<<5);
  }


Jetzt sind wir schon bei 125 ns.
Das geht aber bestimmt noch besser :-)

Bis heute Abend.

von Stefan F. (Gast)


Lesenswert?

>  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.
1
extern void ICACHE_RAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) {
2
  pwm_stop_pin(pin);
3
  if(pin < 16){
4
    if(val) GPOS = (1 << pin);
5
    else GPOC = (1 << pin);
6
  } else if(pin == 16){
7
    if(val) GP16O |= 1;
8
    else GP16O &= ~1;
9
  }
10
}
11
12
void ICACHE_RAM_ATTR pwm_stop_pin(uint8_t pin)
13
{
14
    if(pwm_mask){
15
        pwm_mask &= ~(1 << pin);
16
        if(pwm_mask == 0) {
17
            ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL);
18
            timer1_disable();
19
            timer1_isr_init();
20
        }
21
    }
22
}

von Marc V. (Firma: Vescomp) (logarithmus)


Angehängte Dateien:

Lesenswert?

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
1
    HAL_GPIO_TogglePin(GPIOB, PB0_Pin);


 und einmal mit
1
    GPIOB->ODR=0x00000000;
2
    GPIOB->ODR=0x00000001;

 STM32F103 / 72 MHz

: Bearbeitet durch User
von Lama (Gast)


Lesenswert?

Rein aus Interesse mal ein STM32F030F4 vermessen:

48MHz Systemtakt  -> Pin toggelt mit exakt 4 MHz (entspricht also 250ns)

Code wie bei Daniel B.

von Einer K. (Gast)


Lesenswert?

Zum Arm kann ich nicht viel sagen...

Aber zum Arduino schon.
Arduino UNO, 16MHz, ATMega328P
1
// ausschnitt
2
void loop() 
3
{
4
  for(;;) 
5
  {
6
    digitalWrite(13,!digitalRead(13)); //  54 KHZ auf einem UNO 
7
  }
8
}

Dagegen:
1
#include <CombiePin.h>
2
3
Combie::Pin::OutputPin<4> out;
4
5
int main()
6
{
7
  out.init(); 
8
  for(;;) out.toggle();// 2,667MHz auf einem UNO
9
}
Mehr als 2,667 MHz sitzen nicht drin.
Und das hat auch nix mit Arduino zu tun.
1
// ausschnitt
2
void loop()  // 2,667 MHz symmetrischer Rechteck
3
{ 
4
5
    for(;;) PINB = 0xFF;
6
}


Die beiden loop() Varianten werden ab und zu von der Timer ISR 
unterbrochen.

von Matthias W. (matt007)


Lesenswert?

Stefan U. schrieb:
> Auf ungefähr diese Zeit komme ich beim ESP8266 mit dem Arduino Framework
> bei 80Mhz Systemtakt.

Danke für die Messung Stefan !

von Matthias W. (matt007)


Lesenswert?

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.

von Matthias W. (matt007)


Lesenswert?

Lama schrieb:
> Rein aus Interesse mal ein STM32F030F4 vermessen:
> 48MHz Systemtakt  -> Pin toggelt mit exakt 4 MHz (entspricht also 250ns)

Danke Lama !

von Karl (Gast)


Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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#L74

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.

Karl schrieb:
> arbeitet das mit einem
> sbi PORT, Pin oder einem in, xor, out in wenigen Takten ab

Dr. Sommer schrieb:
> Nö. Sofern die Funktion nicht geinlined wird passiert das zur Laufzeit.

von Purzel H. (hacky)


Lesenswert?

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.

von Einer K. (Gast)


Lesenswert?

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.

von Daniel B. (dbuergin)


Angehängte Dateien:

Lesenswert?

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 ?

von Dr. Sommer (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

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.

von Johnny B. (johnnyb)


Lesenswert?

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.

von Matthias W. (matt007)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

>> 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.

von Daniel B. (dbuergin)


Lesenswert?

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.

: Bearbeitet durch User
von Karl (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

> "the compensation cell should be used"

Was ist das? Kenn ich (noch) nicht.

von Daniel B. (dbuergin)


Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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.

von Einer K. (Gast)


Lesenswert?

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.

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

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.

von Guido Körber (Gast)


Lesenswert?

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.

von Cyblord -. (cyblord)


Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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).

von Daniel B. (dbuergin)


Lesenswert?

Sehr gut, sogar noch mein minimales Oszi-Wissen erweitert heute
Nachtmittag :-)
Dann kann ich leider nicht mehr mitmachen beim Speedrennen....

von Johannes S. (Gast)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

: Bearbeitet durch Moderator
von Matthias W. (matt007)


Lesenswert?

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.

von Matthias W. (matt007)


Lesenswert?

Frank M. schrieb:
> Ja, aber nicht mit der Arduino-IDE compiliert, sondern in Assembler.

nein - in C !

von Dr. Sommer (Gast)


Lesenswert?

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?

von Cyblord -. (cyblord)


Lesenswert?

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.

: Bearbeitet durch User
von Johannes S. (Gast)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Karl (Gast)


Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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?

von Einer K. (Gast)


Lesenswert?

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.

von Matthias W. (matt007)


Lesenswert?

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.

von Matthias W. (matt007)


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

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.

von c-hater (Gast)


Lesenswert?

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.

von Matthias W. (matt007)


Lesenswert?

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.

von Matthias W. (matt007)


Lesenswert?

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.

von Matthias W. (matt007)


Lesenswert?

Dr. Sommer schrieb:
> die auf ARM's vorhandenen
> Speichercontroller (FSMC und FMC

Danke für den Hinweis !

von Johannes S. (Gast)


Lesenswert?

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.

von Dirk (Gast)


Lesenswert?

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.

von Cyblord -. (cyblord)


Lesenswert?

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?

von Daniel B. (daniel_3d)



Lesenswert?

-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

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

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?

von Daniel B. (daniel_3d)


Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

Hab damit noch nicht viel gearbeitet. Vermutlich in den Projekt 
Einstellungen. Oder einfach mal die "Release" Konfiguration auswählen...

von Daniel B. (daniel_3d)


Lesenswert?

Habe was gefunden. Anscheinend steht der Optimization Level auf -Og

von Dr. Sommer (Gast)


Lesenswert?

Mach da mal -O2 draus.

von Daniel B. (daniel_3d)



Lesenswert?

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);
}

von Rolf M. (rmagnus)


Lesenswert?

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/

von Matthias W. (matt007)


Lesenswert?

Rolf M. schrieb:
> Hier noch ein Link, der ganz gut zu beschrieben scheint

Danke für den interessanten Link Rolf !

von Matthias W. (matt007)


Lesenswert?

Daniel B. schrieb:
> -Nucleo-Board mit STM32F103
> -konfiguriert mit CubeMX

Vielen Dank für die Messungen Daniel.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.