Hallo, ich habe mal eine allgemeine Frage zu 8 Bit und 16 Bit. Warum gehen Berechnungen besser, wenn man eine 16-Bit Architektur verwendet? Könnte man größere Werte nicht einfach auf zwei 8-Bit Register aufteilen, oder unterscheiden sich die Rechnungen, also dass eine 16-Bit Berechnung wesentlich aufwendiger mit einem 8-Bit µC wird als mit einem 16 Bit µC?
:
Verschoben durch Moderator
Dann schau dir mal an, was z.B. ein 8-bit-Controller vs. 32-bit-Controller für Codes erzeugen, wenn man z.B. eine 32/16-bit Division macht. Dazwischen liegen Welten. Mehr Silizium bei 32 bit im Core wird gut durch geringe Codegröße im ROM wieder ausgeglichen. Denn auch der Programmspeicher braucht immerhin Silizium. Man muß hier irgendwo mit Augenmaß Minima und Maxima finden... Ich war damals sehr überrascht von den ARM7TDMI (gegenüber 8051-ern), die in den NXP LPC2000-Serien verbaut sind... Da bei 32-bit geht gelegentlich mal ne Division sehr schnell, wobei die sich im 8-bitter auf Grund der Codebreite/Datenbreite einen regelrechten Wolf rechnen muß. Und wenn wir schon mal dabei sind: Ein NXP LPC2129 bei 60 MHz war in Rechenperformance einem SiLabs 8051-er Derivat mit 100 MHz weit überlegen, auch im Energieverbrauch. Ich stellte damals für die Firma als Entscheidungskriterium für einen neuen Controller in einer bestehenden Hardware eine Excel-Matrix mit vielen Parametern auf.
Und bevor ich es vergesse: Was machen eigentlich noch 16-bitter? Ich bin nicht mehr auf dem aktuellsten Stand, aber manche 8-bit-Fabrikanten gingen direkt auf 32 bit über. Z.B. ARM7. Das war eine Welle etwa 2007. Es sei vielversprechend. Ich bin auch dieser Meinung. Zumal sie nicht mehr kosten.
Wilhelm Ferkes schrieb: > Dann schau dir mal an, was z.B. ein 8-bit-Controller vs. > 32-bit-Controller für Codes erzeugen, wenn man z.B. eine 32/16-bit > Division macht. Dazwischen liegen Welten. Ja ok, aber warum ist das so? Kann man nicht denselben Berechnungscode verwenden? Ich kann mir doch auch 32 Bit aus 4*8 Bit denken. Nehmen wir mal eine 32*16 Bit Multiplikation: Da werden doch die Einsen und Nullen einfach multipliziert (wie man es in der Grundschule lernt). Wo ist da denn genau der Unterschied zu einer 8Bit Berechnung. Ihr müsst jetzt nicht so detailliert drauf eingehen...ein Satz als Erklärung würde mir sicher schon langen ;-)
Schau dir mal einen Multiplizierer an. http://de.wikipedia.org/wiki/Multiplizierer_(Digitaltechnik) Dann überleg mal wenn der nur 8 Eingänge (Bit) hat den Befehlsaufwand gegenüber einem mit 16 oder 32 Eingängen (Bit) hat. Addier auch mal die Taktzyklen. Das sollte reichen ;) Hans L
Jürgen Hems schrieb: > Kann man nicht denselben Berechnungscode verwenden? Ich kann mir doch > auch 32 Bit aus 4*8 Bit denken. Das tut man ja auch. Nur dauert es dann entsprechend länger. > Nehmen wir mal eine 32*16 Bit Multiplikation: Viele 32bit Prozessoren rechnen das kombinatorisch in wenigen Takten (typ 2-4). Bei 8bit-Prozessoren wird das schon dreistellig.
Jürgen Hems schrieb: >Wilhelm Ferkes schrieb: >>Dann schau dir mal an, was z.B. ein 8-bit-Controller >>vs. 32-bit-Controller für Codes erzeugen, wenn man >>z.B. eine 32/16-bit Division macht. Dazwischen liegen >>Welten. >Ja ok, aber warum ist das so? >Kann man nicht denselben Berechnungscode verwenden? >Ich kann mir doch auch 32 Bit aus 4*8 Bit denken. Sicher. Das geht auf unterschiedlichen Bitbreiten verschieden schnell, und erzeugt verschieden langen Code, was Rechenzeit und Codespeicher bedeutet. Booaaah Leute, Jürgen, das hatten wir doch alles schon 1980 durchgekaut. Bei einem 8-bitter, wird alles in kleinere Portionen zerstückelt, was größer als 8 bit ist, und endet in riesigen Code-Schleifen. Bitte mach dich da mal in den Details schlau, Rechenalgorithmen, Bitbreiten. Himmelherrgottsakrament!!! Ein 32-bitter rechnet eine 32/16 Division mit einem einzigen Befehl. Für einen 8-bitter muß man das alles in kleine Portionen zerlegen, und eine Division in der Art programmieren, wie wir es in der 4. Klasse Grundschule gelernt haben. Exakt so. In der Hochsprache macht das der Compiler, bzw. implementiert das der Compilerhersteller in den Compiler, in Assembler machst du das alles selbst. Wenn du was nicht verstehst, bitte weiter fragen.
Wilhelm Ferkes schrieb: > Mehr Silizium bei 32 bit im Core wird gut durch geringe Codegröße im ROM > wieder ausgeglichen. Sorry, aber das ist Quatsch. Üblicherweise verbrauchen 32-bit-CPUs durchaus einiges mehr an Code, insbesondere RISC-CPUs. Das liegt einerseits daran, dass sie halt für jeden Befehl 32 bit brauchen, während der durchschnittliche 8-Bitter in vielen Fällen mit kürzeren Befehlen auskommt, andererseits braucht eine RISC-CPU zwei Befehle, um eine komplette Adresse zu laden, da die Befehlswortbreite ja gleich der Adressbreite ist, und man ja irgendwie im Befehl auch noch unterbringen muss, was denn getan werden soll. Dass man mit einem Hardwaremultiplizierer Code beim Multiplizieren und Dividieren einspart, ist sicher keine Frage :), aber derartige Geräte sind ja nun keineswegs an die Befehlswortbreite der CPU gebunden. Alle ATmegas haben beispielsweise auch sowas. 8- oder 16-bit-CPU ist kein wirkliches Thema, das ist eher Marketing. Einerseits können fast alle 8-bit-CPUs auch 16-bit-Operationen (sowas fing ja schon beim Z80 an), andererseits sind typische Controller ganz oft damit befasst, einfach nur mit einzelnen Bits zu jonglieren (Portpin ein- oder ausschalten), da hat man dann keinen Vorteil mehr davon, dass man deren gleich 16 Stück auf einmal statt nur 8 Stück behandeln könnte. Atmel geht mit der Aussage ins Rennen, dass man 16-bit-CPUs gar nicht mehr benötigen würde, TI wird dir sicher glattweg das Gegenteil behaupten. :-)
Jörg Wunsch schrieb: >Sorry, aber das ist Quatsch. Nee, kein Quatsch. Wie schon angemerkt, hatten 8051-er bei Divisionen einen riesigen Codebedarf. Die 32/16-Division geht weit über eine A4-Seite. Analog zur Rechenzeit. Wer es nicht glaubt, bitte mal was compilieren und Code anschauen. Und der belegt auch noch reichlich Flash. Das Gegenteil eben bei einem ARM7. Ich hab das alles selbst getestet, und sowohl mit 8051 als auch mit ARM7 schon gearbeitet. Und auf einem Keil-Seminar zu ARM hab ich das Thema auch mal angesprochen. Die gaben mir Recht. Nun gut, es gibt wohl von Anwendung zu Anwendung Unterschiede.
Jürgen Hems schrieb: > Kann man nicht denselben Berechnungscode verwenden? Ich kann mir doch > auch 32 Bit aus 4*8 Bit denken. Natürlich. Prinzipiell kann ein 32 Bit Prozessor auch nicht mehr als ein 8 Bit Prozessor: Man kan jeden Algorithmus auf jeder der beiden Maschinen implementieren und beide werden zum selben Ergebnis kommen. Aber: Ein 32 Bit Prozessor kann mit größeren Zahlen in einem Rutsch operieren und kann das daher schneller, als wie wenn alles in kleine Häppchen aufgeteilt werden müsste. Du hast doch in der Grundschule das kleine Einmal-Eins gelernt. Die Multiplikationsergebnisse aller Zahlen von 1 bis 9. Das ist der 8-Bitter Wenn du größere Zahlen multiplizeren musst, dann hast du eine Vorschrift, die es dir erlaubt, mit deinem Wissen des Kleinen Einmal-Eins auch größere Multiplikationen durchzuführen. Das dauert zwar ein bischen, aber du kriegst das Ergebnis raus. Stell dir jetzt einfach vor, du hättest anstelle des kleinen Einmal-Eins das Mittlere Einmal-Eins gelernt: Die Multiplikationsergebnisse aller Zahlen von 1 bis 100. Anstelle von 12 * 13 so auszurechnen 12 * 13 ------ 12 36 ------ 156 hast du das Ergebnis schon parat: Du kannst die Multiplikation in einem Schritt machen. Das hilft dir natürlich auch bei größeren Zahlen weiter, weil du eine Vorschrift hast, wie du jede beliebige Multiplkation so aufteilen kannst, dass du deine mittleres Einmal-Eins Basisfunktionalität effizient einsetzen kannst. Da du 2 stellige Zahlem schnell multiplizeren kannst, bist du natürlich gegenüber denjenigen im Vorteil, die noch einen Schritt weiter gehen müssen und alles auf ihre Kleines Einmal-Eins Wissen herunterbrechen müssen. Geh noch einen Schritt weiter. Dein Großes Einmal-Eins befähight dich dazu, alle Zahlen von 1 bis 1000 ohne groß nachrechnen zu müssen zu multiplizeren. Wo die 'kleinen' Rechner schon lange kompliziert rechnen müssen (6523 * 9823), hast du das Ergebnis in einem Schritt parat. Und was jetzt hier für Multiplkationen gilt, gilt auch für Additionen, Subtraktionen etc. 32 Bit Rechner können einfach größere Zahlen in einem Rutsch bearbeiten, ohne die Operation in Teiloperationen aufteilen zu müssen. Vor den 8 Bit Prozessoren gab es übrigens auch 4 Bit Prozessoren. Die ersten Taschenrechner basierten oft auf einer 4-Bit Architetkur. Dann gab es auch noch Bit-Slice Prozessoren. Bei denen konnte man mehrere Prozessoren aneinanderschalten und sich so beliebige Wortbreiten je nach Bedarf zusammenstellen.
Wilhelm Ferkes schrieb: > Wie schon angemerkt, hatten 8051-er bei Divisionen > einen riesigen Codebedarf. Da vergleichst du ja auch Äpfel mit Ananas. Dann guck dir doch mal den Codebedarf einer 32-bit-RISC-CPU an, wenn du die Division in Software schreibst. Dein Codeunterschied hat doch in erster Linie was damit zu tun, dass ein Prozessor einen Hardwaremultiplizierer hat und der andere nicht, nicht aber damit, dass der eine mit einem 32 bit breiten Bus arbeitet und der andere nur mit 8 bit. Wenn du jetzt noch dazu nicht gerade 32-bit-Zahlen beispielsweise auf einem ATmega dividieren lässt, sondern 16-bit-Zahlen (um in dem Bereich zu bleiben, wo der 8bitter vor allem seine Daseinsberechtigung hat), dann wirst du schnell feststellen, dass eben auch ein ARM7 nicht die eierlegende Wollmilchsau ist, sondern ebenso sein abgegrenztes Aufgabengebiet hat, in der er glänzt, wie das die kleineren Controller für sich auch haben.
Jörg Wunsch schrieb: > Befehlen auskommt, andererseits braucht eine RISC-CPU zwei Befehle, > um eine komplette Adresse zu laden, Wobei Programmierung für grössere Programme (wie die auf PCs, und generell objektorientierte Programmierung) solche absoluten Adressen nicht so häufig verwendet wie kleine Controller-Programme es tun. Eher werden Pointer rauf und runter durchgereicht. Weit häufiger findet man aber Pointer-relative Adressierung, mit der sich andererseits diverse 8bit Controller etwas schwer tun. Etwas umständlich tun sich 8bit Architekturen oft mit der Adressierung lokaler Daten auf einem Stack. Manche kommen damit so schlecht zurecht (z.B. 8051, PIC[non-extended]), dass Compiler es vorziehen, auch lokale Daten der Klasse "auto" absolut zu adressieren, was Funktionen non-reentrant macht und insbesondere bei Interrupts haarig werden kann. Das ist zwar keine prinzipielle Sache von 8bit Architekturen, aber recht verbreitet. Auch AVRs tun sich nicht wirklich leicht mit Daten auf dem Stack, insbesondere wenn man wie der GCC nur einen Stack verwendet. Wenn man Prolog/Epilog von Funktionen mit Daten auf den Stack ansieht, dann sticht das ins Auge. Solche Funktionen, vor allem wenn auch noch reichlich Registerverwendung dabei ist, haben bei AVRs einen erheblichen Wasserkopf, viel aufwendiger als ARMs (auch hier gilt: Das ist eher Atmel anzulasten, das hätte man auch effizienter hinbekommen). 8/16bit Architekturen neigen aufgrund der naheliegenden Beschränkung auf maximal 64KB Datenadressraum zu Adressraumtrennung, oder zumindest zu Adressräumen unterschiedlicher Grösse und Adressbreite für Code und Daten. Wenn dies - wie meistens - dazu führt, dass Konstanten im Flash nicht mit normalen Pointern adressierbar sind, dann wird es für den Programmierer entweder umständlicher (doppelte Funktionen, je nach Art der Adresse) oder langsamer (generic pointer mit runtime-Funktionen zur Dereferenzierung). Bei 32bit Architekturen entfällt diese Problematik.
Ein weiteres prinzipielles Problem von 8bit Architekturen ist die Sprachdefinition von C, die historisch bedingt von 16bit-Arithmetik ausgeht (oder mehr). Ein Compiler kann versuchen, überflüssige Erweiterungen zu vermeiden, aber das hat Grenzen. Nicht selten findet man daher Compiler, die es im Interesse kompakten Codes vorziehen, mit 8bit Daten konsequent auch dann in 8bit-Breite zu rechnen, wenn das Ergebnis nicht mehr den Regeln von C entspricht. Generell ist die Abbildung von C auf die jeweilige Maschine bei vielen 8bit Prozessoren deutlich verkrampfter als bei 16/32bit Prozessoren. Das liegt natürlich oft am Alter, denn viele 8bit Architekturen entstanden in ihrem ggf. später variierten Kern vor dem Siegeszug von Programmierung mit Compilern, sind folglich nicht auf deren Anforderungen hin optimiert. AVR ist zwar jünger, aber auch da hätte man manches besser machen können. Auch bei den ersten 16bit Architekturen lief das recht unterschiedlich ab. So hatte die 68000-Schiene über die Anlehnung an das PDP-11 Vorbild weniger Probleme mit Sprachen der Pascal/C-Schiene als die Z8000, bei der sich Zilog eher an den Anforderungen von Fortran und Cobol orientierte. Die heute verbreiteten 32bit Architekturen sind hingegen schon von Anfang an für Hochsprachenprogrammierung ausgelegt worden.
A. K. schrieb: > Auch AVRs tun sich nicht wirklich leicht mit Daten auf dem Stack, > insbesondere wenn man wie der GCC nur einen Stack verwendet. Die haben halt damals beim Entwurf nicht über den Tellerrand in Richtung GCC geguckt, sondern sich ausschließlich auf die Kommentie- rung durch die Haus- und Hoflieferanten von IAR verlassen, denen wiederum ein kombinierter Daten- und Returnstack ein Fremdwort ist. Ergo: alles, was IAR nicht gebraucht hat, ist im AVR nicht drin. Das, was sie zum effektiven Implementieren der Hochsprache gebracht haben, hat jedoch Einzug gefunden (wie beispielsweise ein drittes Zeigerregister, ist in irgendeinem Dokument beschrieben). Das Problem einer 8-bit-Architektur gegenüber der 16-bit-int-Forderung von C dürfte eher der AVR-GCC-Implementierung denn der 8-bit-CPU anzulasten sein. Die ist, wie mir Björn Haase mal sagte, eigentlich eher eine Implementierung eines Pseudo-16-bit-Prozessors statt die eines echten 8-Bitters. Hier zeigt IAR ja, dass man das in der Tat besser machen kann.
Jörg Wunsch schrieb: > Die haben halt damals beim Entwurf nicht über den Tellerrand in > Richtung GCC geguckt, sondern sich ausschließlich auf die Kommentie- > rung durch die Haus- und Hoflieferanten von IAR verlassen, denen > wiederum ein kombinierter Daten- und Returnstack ein Fremdwort ist. Genervt hat mich allerdings, dass sie dies auch nicht mit den Xmegas ausgebügelt haben, wo die Sache doch schon längst zum Himmel stank und das exakt der richtige Zeitpunkt gewesen wäre. Dinge wie atomare Manipulation von SP und push/pop mit Registerlisten (unterbrechbar) wären m.W. allemal drin gewesen und hätten Prolog/Epilog massiv verkürzt. Es fällt wirklich unangenehm auf, wenn man den Prolog/Epilog-Code von AVR mit dem von ARM vergleicht. > Das Problem einer 8-bit-Architektur gegenüber der 16-bit-int-Forderung > von C dürfte eher der AVR-GCC-Implementierung denn der 8-bit-CPU > anzulasten sein. Mir ist klar, dass GCC hier ganz spezielle Probleme hat, weil das im maschinenunabhängigen Teil einfach nicht vorgesehen ist, es aber dort realisiert werden müsste. Aber es gibt schon einige Stellen, bei denen die Optimierung auch durch andere Compiler Grenzen hat, wie beispielsweise bei "if (i+1 < n)" und bei Schiebeoperationen.
Wilhelm Ferkes schrieb: > Nee, kein Quatsch. Wie schon angemerkt, hatten 8051-er bei Divisionen > einen riesigen Codebedarf. Die 32/16-Division geht weit über eine > A4-Seite. Analog zur Rechenzeit. Wer es nicht glaubt, bitte mal was > compilieren und Code anschauen. Und der belegt auch noch reichlich > Flash. Das Gegenteil eben bei einem ARM7. Ich hab das alles selbst > getestet, und sowohl mit 8051 als auch mit ARM7 schon gearbeitet. Doch Quatsch, der ARM7TDMI hat garkeine Division, der 8051 sehr wohl. Die 8Bit-Division ist daher beim 8051 schneller und kleiner. Und der Codebedarf der 16-,32Bit-Lib fällt immer nur bei dem ersten Aufruf an. Die 32Bit-Division sieht nur deshalb so groß aus, weil sie auf Schnelligkeit getrimmt ist. Sie besteht aus 4 einzelnen Divisionsroutinen, je nachdem, ob durch 8,16,24 oder 32Bit dividiert wird. Die höherwertigen Register werden zu Anfang auf 0 getestet und dann die entsprechende Routine ausgeführt. Die float Grundrechenarten (+-/*) des Keil C51 belegen nur etwa 1kB. Dürfte beim ARM deutlich größer sein. Peter
Peter Dannegger schrieb: > Die float Grundrechenarten (+-/*) des Keil C51 belegen nur etwa 1kB. > Dürfte beim ARM deutlich größer sein. Wobei da gerne mal Äpfel mit Birnen verglichen werden, etwa IEEE-konforme Implementierung (korrekte Rundung, NaN, Denormals, ...) mit quick-and-dirty Implementierungen, die nur auf kleinen/dichten Code abzielen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.