Forum: Mikrocontroller und Digitale Elektronik 16-bit vs. 32-bit Division auf 8-bit AVR


von Jan (Gast)


Lesenswert?

Hallo zusammen,

ich muss eine Division rechnen auf einem AVR 8-bit (Atmega88).

Ich habe nun 2 Möglichkeiten:

Das ganze in 32-bit zu rechnen also 32-bit geteilt durch 32-bit mit 0% 
Fehler.
Oder die 32-bit zahlen mit einem Zweierkomplement vorher "prescalen" 
(also durch rechtsschieben) auf 16-bit und dann 16-bit geteilt durch 
16-bit zu haben und dann aber mit max. 1,4% Fehler (was nicht wirklich 
tragisch wäre für die Anwendung).

Die Berechnung geschieht nicht zeitkritisch in main(). Sämtliche 
zeitkritischen Sachen sind in Interrupts untergebracht. Habe ich einen 
großen Zeitvorteil durch das herunterbrechen auf 16-bit? Derzeit lasse 
ich es mit 32-bit dividieren und mekre so keinen Nachteil. Da ich aber 
am Ende gerne noch optimiere, nachdem alles läuft, um noch etwas 
Speicher und Geschwindigkeit zu holen, bin ich nun bei dieser Division 
angelangt.

Macht es eigentlich einen Unterschied, ob man 16-bit durch 16-bit teilt 
oder 16-bit z.b. nur durch 8-bit? Oder ist sowieso immer der größte 
Operand ausschlaggebend?

Danke.

LG
Jan

von Falk B. (falk)


Lesenswert?

@  Jan (Gast)


>Das ganze in 32-bit zu rechnen also 32-bit geteilt durch 32-bit mit 0%
>Fehler.

Naja, einen Rest gibt es fast immer, es sind ja Festkommazahlen.

>Oder die 32-bit zahlen mit einem Zweierkomplement vorher "prescalen"
>(also durch rechtsschieben) auf 16-bit und dann 16-bit geteilt durch
>16-bit zu haben und dann aber mit max. 1,4% Fehler (was nicht wirklich
>tragisch wäre für die Anwendung).

Klingt nicht sinnvoll.

>Die Berechnung geschieht nicht zeitkritisch in main().

Dann mach einen normale 32 Bit Division und gut.

>>zeitkritischen Sachen sind in Interrupts untergebracht. Habe ich einen
>großen Zeitvorteil durch das herunterbrechen auf 16-bit?

Wozu, wenn es NICHT zeitkritisch ist?
Ich glaube nicht, dass man da viel spart, schon gar nicht in Summe wenn 
man den Programmieraufwand dazuzählt.

http://www.mikrocontroller.net/articles/AVR-GCC-Codeoptimierung#Prinzipien_der_Optimierung

>Macht es eigentlich einen Unterschied, ob man 16-bit durch 16-bit teilt
>oder 16-bit z.b. nur durch 8-bit?

AFAIk nein.

> Oder ist sowieso immer der größte Operand ausschlaggebend?

Ja.

von Ralf G. (ralg)


Lesenswert?

Sind das 'vollkommen zufällige' Divisionen? Oder Division durch 
Konstanten?

Jan schrieb:
> Das ganze in 32-bit zu rechnen also 32-bit geteilt durch 32-bit mit 0%
> Fehler.
> Oder die 32-bit zahlen mit einem Zweierkomplement vorher "prescalen"
> (also durch rechtsschieben) auf 16-bit und dann 16-bit geteilt durch
> 16-bit zu haben und dann aber mit max. 1,4% Fehler (was nicht wirklich
> tragisch wäre für die Anwendung).

'C' oder Assembler? In Assembler gibts ja keine Datentypen, da nimmt man 
sozusagen 40Bit oder 48Bit und macht das umgekehrt: z.B. Division durch 
10:  erst 'mal' 6554 und die letzten 16Bit 'weglassen'. Ob der Compiler 
das so optimiert, wenn du ihm große Datentypen vorgibst, habe ich noch 
nicht getestet.

von Karl H. (kbuchegg)


Lesenswert?

Mein genereller Leitfaden sieht so aus

  Machs erst richtig, und dann machs schnell


Denn
ein Programm welches etwas langsamer ist (aber nicht zu langsam) und 
richtig rechnet, ist immer noch ein nützliches Programm
ein Programm, welches aber pfeilschnell falsche Werte ausrechnet, ist 
niemandem nütze.

von Jan (Gast)


Lesenswert?

Hallo,

also eines davon ist eine Konstante, der Divisor ist aber ein 
"zufälliger" Wert, der über ein Zeitintervall (vom Timer) kommt.

Geschrieben habe ich es in C.

Das mit der Division durch 10 ist interessant, das muss ich mir mal 
anschauen, wie das genau "so geht". Da ich in anderen Programmen 
manchmal durch 100 teile...

@ Falk

Bezüglich Festkommazahlen: genau deswegen ist es 32-bit, da ich die 
Kommastellen "gedacht verschiebe" (Festkommaarithmetik). Daher ist der 
Fehler erst in der ganz und gar nicht interessierenden 3. 
Nachkommastelle.
Breche ist das auf 16-bit eben runter, kommt der Fehler in der 1. 
Nachkommastelle. Für den mich interessanten Bereich wären es dann eben 
1,4% Fehler.

Der Programmieraufwand wäre ja nicht groß. Entsprechend rechtsschieben, 
die Konstante vom Compiler dividieren lassen, Datentypen ändern und wie 
gehabt dividieren.

Danke für die Info mit dem größten Operand, was dazu gelernt und 
gespeichert :-)

@ Karl Heinz
da stimme ich dir voll und ganz zu. Das ist eine sinnvolle Divise. Nur 
die 1,4% sind eigentlich vertretbar, zumal die sowieso nur im äußersten 
Grenzbereich auftreten (wenn der Timer-Wert sehr klein wird und die 
Auflösung für das "prescalen" dann leidet). In 75% Fälle der 
ausgewerteten Daten die verwertet werden, liegen wir bei der Hälfte 
(0,7%) oder sogar darunter und das ist für die Anwendung völlig 
akzeptabel.

von Zottel (Gast)


Lesenswert?

Das nennt man dann Fehlerrechnung. Den Einfluss der einzelnen Parameter 
auf den Gesammtfehler erarbeiten. siehe
http://de.wikipedia.org/wiki/Fehlerfortpflanzung

von Ingo (Gast)


Lesenswert?

Also wenn es nicht zeitkritisch ist, dann kannst du es doch in 32 Bit 
rechnen. Wenn ich teilweise Temperaturen eines NTCs berechne, lass ich 
den AVR teilweise Polynome 3. oder 4. Gerades in Float lösen. Was solls, 
wenn der Messwert nicht oft oder schnell gebraucht wird, kein Ding. Man 
muss ja nicht im jeden Durchlauf rechnen, die Temperatur muss man ja nur 
alle 5s mal rechnen.

Also ich würde es so lassen...


Ingo

von tobi (Gast)


Lesenswert?

Jan schrieb:
> Geschrieben habe ich es in C.

Dann lass es den Compiler machen -- er ist (i.d.R) da viel besser

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.