Forum: Mikrocontroller und Digitale Elektronik 8 bit vs. 16 bit


von Jürgen H. (misteret)


Lesenswert?

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
von Purzel H. (hacky)


Lesenswert?

Na, 16 bit aufs Mal benoetigt mehr Silizium....

von Wilhelm F. (Gast)


Lesenswert?

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.

von Wilhelm F. (Gast)


Lesenswert?

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.

von Jürgen H. (misteret)


Lesenswert?

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

von Hans L. (hansl)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von Wilhelm F. (Gast)


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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

von Wilhelm F. (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.