Liebes Forum!
Ich habe eine Verständnisfrage:
Ein µC braucht ja für unterschiedliche Befehle unterschiedlich lange
(außer ich programmiere in Assamblersprache). Kann ich sagen, dass bei
einem Takt von 100MHz ein Befehl (ein Schritt) 10ns dauert außer er ist
komplizierter?
Wenn das total falsch ist, wie ist das mit Takt und
Rechengeschwindigkeit?
DANKE im Voraus!
LG
Harald
Auch in Assembler brauchen Befehle i.A. unterschiedliche Zeiten zur
Ausführung.
Die "Befehle" wie "lade Akku mit dem Inhalt der Speicherzelle 0x1234"
werden meist intern noch in Mikrooperationen zerlegt. Um bei dem
Beispiel zu bleiben:
Erster Schritt = lege die Adresse für den nächsten Befehl auf den
Adressbus des Programmspeichers.
Zweiter Schritt = lesen das erste Byte des Befehls
Dritter Schritt = dekodiere den Befehl, um zu sehen, wie es weiter geht
Vierter Schritt = lese den Rest des Befehls
Fünfter Schritt = lege die Adresse 0x1234 auf den Adressbus des
Datenspeichers
Sechster Schritt = lese das Byte aus dem Datenspeicher und packe es in
den Akku.
Das Ganze kann bei unterschiedlichen Prozessorarchitekturen anders
ablaufen, es werden u.U. einige Schritte zusammengefasst.
Und leider ist das ganze dann noch viel komplizierter. Denn ein moderner
uC kann viele dieser oben genannten Schritte parallel ausführen, das
nennt man dann pipelining. Zum Beispiel sind dann immer die nächsten
fünf Befehle in der Pipeline. Während er das Resultat eines Befehls in
den Speicher zurückschreibt, berechnet er schon das Resultat des
nächsten und holt sich die Parameter des übernächsten vom Speicher
etcetc.
Was aber, wenn ein (bedingter) Sprung vorkommt? Dann muss er für einige
Befehle, die er schon vorbereitet hat, die (teil-)Resultate wieder
wegwerfen. Nun gibt noch so schlaue Kerlchen, die versuchen,
herauszufinden, ob der bedingte Sprung ausgeführt wird oder nicht, oder
aber er rechnet einfach beide Varianten,..... etcetc.
Dann ist da manchmal noch der Cache. Der macht es nochmls
komplizierter....
Du siehst, so einfach ist das nicht. Darum gibt es Benchmarks. :-)
Gruäss
Simon
Man kann keinerlei allgemeingültige Aussagen dadrüber machen.
Die einzigste aussagekräftige Aussage findest du im Datenblatt deines
Prozessors wie lange ein Befehl dauert. Es gibt verschiedene Ansätze und
verschiedene Implementierungen. Der eine brauch mehrere Takte, was ein
andere in einem Takt macht. Auch verschiedene Strukturen von
Neumann/Haward führt zu unterschiedlichen Ergebissen.
Eine halbwegs zuverlässige Aussage über die Rechengeschwindigkeit deines
µC kriegst du in aller Regel nur über eine Messung (z.B. mittels DSO &
Pin-Toggle).
Gruss
Harald schrieb:> Ein Schritt in Deinem BSP. würde aber 10ns (bei 100 MHz) brauchen oder?
Jein... speziell bei den Prozessoren der heutigen PCs ist der Speicher
drastisch langsamer als der Prozessor. Es müssen also Warteschritte
eingelegt werden. Moderne Prozessoren nutzen die Wartezeit für andere
Tätigkeiten oder laden auf Verdacht schon mal mehrere Bytes am Stück
(weil das schneller geht als sie einzeln anzufordern).
Generell gilt nur, dass keine Operation schneller ablaufen kann als "1
Schritt", wohl aber langsamer.
Zwei Beispiele aus der Steinzeit, als alles noch einfacher war:
- Die MCS51 Familie brauchte immer 12 Takte für eine Operation. Jeder
Befehl wurde in maximal 2 Operationen abgearbeitet.
- Der Z80 brauchte 4 bis 23 Takte für einen Befehl
Aber wie oben schon geschrieben: Heute ist es deutlich komplexer. Und
Antworten auf die einfachen Fragen sind die schwersten.
Moin
kommt im wesentlichen immer auf die Architektur an.
Ganz alte system, kannten noch keine Piplining. aber auch hier hat ein
Befehl z.B. mindestens 4 Taktzyklen gebraucht. Komplexere sachen wie
bedingte sprünge, multiplikationen / divisionen benötigten dagegen
einige mehr. Grund ist, das ein ASM Befehl für die keine spezielle HW
vornahnden ist intern in Microcode umgesetzt wird der dann entsprchend
länger braucht.
Z.B. der Uhr 8086 oder der 8051. CISC Befehlssatz.
Andere Systeme hatten genau aus der problemeatik heraus, das die
laufzeit der Programme recht komplex zu berechnen ist, und das der
gleiche befehl je nach registerwerten unterschiedlich lang laufen kann
einen anderen ansatz. Der Befehlssatz wurde auf das nötigste beschränkt,
und alle befehle benötigen genau gleich lang. RISC Befehlssatz.
Da Befehle in der internen abareitung die oben bereits genanten zustände
durchlaufen müssen. Decode LoadData Execute StoreData (oder auch
mehrere)
kam man auf die idea dise zustäne prallel / versetzt durchzuführen. Die
Pipline war geboren. Je schneller die CPUs wurden um so grösser wurden
diese damals. was sich schlecht auf das Sprungverhalten auswirkte, da
alles was in der Piplen stand unterumständen falsch war und die pipline
erst wieder gefüllt werden musste.
Zusätzlich können heutige CPUs mehrere befehle gleichzeitig verarbeitet.
Z.B. mehrere einfache integer operationen, eine Flot operation und eine
matrixoperation gleichzeitig. Was nun dazu führt, das die
befehlsreihenfolge entscheident für die abarbeittungsgeschwindigkeit
ist. kommen 2 flot befehle direkt hintereinander und danach 4 int
befehle, dauert das länger als wenn 1 flot 2 int wieder ein flot und die
restlichen 2 int befehle kommen wúrde.
um das ganze noch komplizierter zu machen, sortieren moderne CPUs die
befehle selbständig um, um das sytem bestmöglichst auszulasten. Es wird
natürlich nur so umsortiert, das das ergebniss icht verfälscht wird. Out
of Order.
Das gleiche passiert beim piplining. es wird eine Sprung vorhersage
getroffen, um die pipline vermutlich richtig zu füllen.
Und um dem noch die krone auf zu setzen, werden unter umständen beide
pfade berechnet, bis klar ist welcher von beiden der richtige war. um
dann das ergebniss des falschen pfades zu verwerfen.
und für die laufzeit ist auch das speicher und cach verhalten mit
entscheident. Noch mehr voodoo
PS. Bei Intelsystemen kann/konnte das BIOS z.B. dein Microcode der CPU
Patchen um ggf fehler in der CPU nachträglich zu Fixen.
123 schrieb:> Ganz alte system, kannten noch keine Piplining. aber auch hier hat ein> Befehl z.B. mindestens 4 Taktzyklen gebraucht.
Was natürlich falsch ist, sie brauchten mindestens 1 Taktzyklus. Warum
soll z.B. ein NOP Befehl mehr brauchen als 1 Taktzykus? Nur die 80x86
Schiene brauchte immer jede Menge Taktzyklen. Die liefen erst mit 8MHz
so schnell wie z.B: der 6502 mit 1 MHz, der z.B für viele Befehle nur 1
Taktzyklus braucht.
Georg G. schrieb:> Jein... speziell bei den Prozessoren der heutigen PCs ist der Speicher> drastisch langsamer als der Prozessor.
.. eigentlich geht es hier um uC und nicht um Desktop Prozessoren und da
ist der Speicher eigentlich nicht deutlich langsamer.
Bei den AVR's gehts am einfachsten. Die meisten Befehle benötigen einen
oder zwei Takte. (siehe Befehlsliste im Datenblatt) Deshalb auch die
Einschränkung auf "nur" 132 Befehle. (RISC-Befehlssatz, reduced
instruction set).
Bei Programmierung in C oder höher wird der Befehlssatz bis ins
Unendliche aufgebläht. Schon bei den einfachsten Befehlen wird die
Ausführungszeit unübersichtlich, weil gleich eine komplette Bibliothek
mit ins Programm eingebunden wird.
Ein Beispiel: Was in Assembler nur etwa 20Byte Speicher beansprucht (1ms
Verzögerung+Ausgabe auf eine LED) wird bei Arduino-C gleich ca. 1600
byte belegen.
Mik schrieb:> Was natürlich falsch ist, sie brauchten mindestens 1 Taktzyklus. Warum> soll z.B. ein NOP Befehl mehr brauchen als 1 Taktzykus? Nur die 80x86> Schiene brauchte immer jede Menge Taktzyklen.
Die Ausführungszeit der Befehle ist bei PC-Prozessoren eine
Definitionssache. Zählst du die Zeit zwischen fetch und retirement, oder
nur die Zeit in execution units. Im ersten Fall kriegst du eine völlig
vom Kontext abhängige zweistellige Anzahl Takte raus, im zweiten Fall
kann es auch 0 sein (z.B. besagter NOP).
> so schnell wie z.B: der 6502 mit 1 MHz, der z.B für viele Befehle nur 1> Taktzyklus braucht.
Kein einziger Befehl des 6502 war in 1 Takt fertig. Ausserdem ist das
eine Milchmädchenrechnung, denn die Kehrseite davon war eine gegenüber
beispielsweise Z80 viel niedrigere Taktfrequenz.
> .. eigentlich geht es hier um uC und nicht um Desktop Prozessoren
Eben. Die hier betrachtete Frage ist bei einfachen µCs noch recht
einfach zu beantworten, aber bei PC-Prozessoren ist das eine
hochkomplexe Angelegenheit.
Peter R. schrieb:> Ein Beispiel: Was in Assembler nur etwa 20Byte Speicher beansprucht (1ms> Verzögerung+Ausgabe auf eine LED)
... belegt in vernünftig geschriebenem C auch nicht wesentlich mehr.
> wird bei Arduino-C gleich ca. 1600> byte belegen.
Das ist aber ein Problem des Komforts, der mit den Arduino-Bibliotheken
mitkommt.
Man kann mit einem Gleitschirm die Alpen von Nord nach Süd überqueren.
Kann man. Aber an Bord einer 737 ist der Flug von München nach Mailand
dann doch um einiges bequemer. Das ist alles nur eine Frage der
persönlichen Vorlieben. Der eine sieht es als sportliche
Herausforderung, der andere will einfach nur nach Mailand und
zwischendurch mal was Warmes essen.
Nu ja MCUs mit ARM7 und CortexM3 / M4 erreichen mitlerweile auch schon
fast geschwindigkeiten wo der Flash nicht mehr hinterher kommt, und SRAM
entweder extrem teuer wird oder mit Waitstates betrieben wird.
LPC2888 128Bit Flash + ARM 7 (72Mhz) mit 8 KB cach Wieso organisieren
die bei einer 32Bit RISC Architektur das Flash mit 128 bit?
Und in welche Klasse gehört ein Cortex A8 A9 A15?
Peter R. schrieb:>> Bei Programmierung in C oder höher wird der Befehlssatz bis ins> Unendliche aufgebläht.
Sorry der Befehlssatz vom uC bleibt der gleiche.
> Schon bei den einfachsten Befehlen wird die> Ausführungszeit unübersichtlich, weil gleich eine komplette Bibliothek> mit ins Programm eingebunden wird.
Nein, wenn du einfachen Code schriebst wird der sehr effektiv in
Assembler umgesetzt.
Wenn du natürlich für jede Kleinigkeit Megafunktionen aufrufst, wird
auch der entsprechende Wasserkopf mit eingebaut.
Wenn du printf benutzt, um einen einfachen Sting auszugeben statt z.B.
putstr mußt du dich auch nicht wundern wenn den Code viel größer wird.
Wenn du statt i*3 mit f*3. rechnest muß Du dich nicht wundern wenn Dein
Code gleich viel größer wird.
> Ein Beispiel: Was in Assembler nur etwa 20Byte Speicher beansprucht (1ms> Verzögerung+Ausgabe auf eine LED) wird bei Arduino-C gleich ca. 1600> byte belegen.
Wenn Du Wasserköpfe einbaust musst du Dich nicht wundern Wenn sich
alles aufbläht. Das liegt aber nicht an C sondern an den Bibliotheken
wie du anforderst einzubauen.
Wenn du in C schreibst ist es fast genauso groß als wenn du es in
Assembler direkt schreibst. Ein guter Assembler Programmierer wird es
kürzer schreiben können, ein schlechter wird es länger schreiben da C
recht gut optimiert.
123 schrieb:> Und in welche Klasse gehört ein Cortex A8 A9 A15?
Das beantwortet schon der Name, das "A" für Application.
Anwendungsprozessoren für Handy, Tablets etc. Als Mikrocontroller sind
sie eher selten. Embedded Linux-Systeme solchen Kalibers betrachte ich
auch dann nicht als Mikrocontroller, wenn man einem RPI eine LED blinken
lässt.
123 schrieb:> Nu ja MCUs mit ARM7 und CortexM3 / M4 erreichen mitlerweile auch schon> fast geschwindigkeiten wo der Flash nicht mehr hinterher kommt, und SRAM> entweder extrem teuer wird oder mit Waitstates betrieben wird.
Welcher davon betreibt sein internes SRAM mit Waitstates?
Daumenregel: Je schneller ein Prozessor ist, ob µC oder nicht, desto
komplexer ist das Laufzeitverhalten, wenn man es auch einzelne Befehle
und Takte runterbricht.
A. K. schrieb:> Ausserdem ist das> eine Milchmädchenrechnung, denn die Kehrseite davon war eine gegenüber> beispielsweise Z80 viel niedrigere Taktfrequenz.
Es ist auch eine sehr negative Eigenschaft wenn man eine 8 fach
langsamen Takt braucht um das gleiche zu erreichen. Ja sehr schlimm, Ein
viel höherer Takt um das gleiche zu erreichen ist ja auch viiiiel
besser. Wow hast du da jetzt eine pöse pöse Kehrseite vom 6502
aufgedeckt Du bist der Held des Tages.
A. K. schrieb:> aber bei PC-Prozessoren ist das eine hochkomplexe Angelegenheit.
Das es da komplexer ist ist ja auch keine Frage. Klar wir könnten auch
noch über Herzopersatonen reden, ist auch keine einfach Sache, aber um
das geht es hier genausowenig.
Mik schrieb:> Es ist auch eine sehr negative Eigenschaft wenn man eine 8 fach> langsamen Takt braucht um das gleiche zu erreichen. Ja sehr schlimm, Ein> viel höherer Takt um das gleiche zu erreichen ist ja auch viiiiel> besser. Wow hast du da jetzt eine pöse pöse Kehrseite vom 6502> aufgedeckt Du bist der Held des Tages.
Hab ich deinen Liebling beleidigt? ;-)
Es ist weder negativ noch positiv. Letztlich zählt, was hinten
rauskommt.
Erreichbare Taktfrequenzen sind eine Frage der Gattertiefe pro Takt.
Wenn zwischen zwei Takten 10 Gatterlaufzeiten liegen, dann kann man
schneller takten, als wenn dazwischen 20 Gatterlaufzeiten liegen. Je
mehr man in einen Takt quetscht, desto langsamer wird der Takt. Daher
kann bei gleicher Herstellungtechnik der eine Chip bei 1 MHz am Ende
sein, während der andere Chip 2,5 MHz schafft, aber dafür pro Takt
weniger leistet.
War der AMD K5 überlegen, weil sein Cache nur einen Takt benötigte und
er in der Lage war, 4 Befehle pro Takt auszuführen, während die
Konkurrenz 2 Takte für den Cache benötigte und nur 2 Befehle pro Takt
erledigte? Nein, das war er nicht, weil Intel zwar weniger pro Takt
erledigte, aber wesentlich schneller taktete. Umgekehrt taktete Intels
Pentium 4 zwar schneller als AMDs K8, erledigte (bei gegebener
thermischer Grenze) aber oft weniger Arbeit.
Wie die Bilanz "hoher Takt mit wenig Arbeit pro Takt" (speed deamon) vs
"niedriger Takt mit viel Arbeit pro Takt" (brainiac) ausfällt, das weiss
man nicht immer im Vorhinein. Mal geht es so aus, mal so. Was heute so
in schnelleren PCs so rumläuft ist ein Kompromiss aus beidem.
>> aber bei PC-Prozessoren ist das eine hochkomplexe Angelegenheit.> Das es da komplexer ist ist ja auch keine Frage. Klar wir könnten auch> noch über Herzopersatonen reden, ist auch keine einfach Sache, aber um> das geht es hier genausowenig.
Ich war es nicht, der die x86 in die Diskussion einbrachte. Aber die
Frage der Bilanz Takt vs Komplexität ist im µC-Umfeld ebenso zu finden.
Die 8051 brauchten früher 12 Takte pro Operation, takteten aber auch
viel schneller.
Ok Internes SRAM sollte normalerweise 0 Wait states haben. Sollte auch
mittlerweile gross genug sein. Wobei sich da auch mehrere darum
gleichzeite schlagen können. DATA CODE und DMA. Daher vermutlich auch
die zerstückelung in verschiedene häpchen wie z.B. LPC 4xxx
Und zum Flash hab ich teilweie auf die schnelle keine aussage finden
können. Beim STM32F427xx scheint der flash nur 30Mhz zu können der core
bis zu 168MHz.
Das ist auch das große Problem bei alle einfacheren ARM's und Cortexen:
sie haben keinen Befehlscache und auch ein sauschneller interner
Flashrom kommt selten unter die 45 ns-Marke. Konsequent haben NXP und
teilweise auch ST versucht, durch höhere Datenbreite zum Flash hin den
"flash"enhals zu erweitern, aber bei ST entsinne ich mich dunkel, daß da
bei 72 MHz schon 3 waitstates nötig gewesen sind.
Ne echte Alternative wären (wenn sie denn weiter verbreitet wären!)
einige der Fujitsu-FR Controller. Dort gibt es Typen mit Befehlscache
und aus eigenem Vergleich weiß ich, daß die einem gleich schnell
getakteten ARM glatt davonrennen.
W.S.
W.S. schrieb:> und auch ein sauschneller interner> Flashrom kommt selten unter die 45 ns-Marke.
Hm.
Renesas Monos Flash -- z.B. im RX-Controller -- läuft bis 100 MHz ohne
Waitstates.
So long,
Tillomar