Forum: Mikrocontroller und Digitale Elektronik Floating point division auf 8-Bit Prozessor


von Fabian F. (fabian_f55)


Lesenswert?

Moin moin,

weiß jemand zufällig wie viele Prozessorschritte eine Division von zwei 
float oder double auf einem 8-Bit-Prozessor ohne floating-point modul 
dauert?
Ich habe das Gefühl ewig, aber bevor ich mir die Mühe mache das mit dem 
Oszi auszumessen, weiß das vielleicht jemand aus dem Kopf?

von Ingo L. (corrtexx)


Lesenswert?

Fabian F. schrieb:
> Ich habe das Gefühl ewig, aber bevor ich mir die Mühe mache das mit dem
> Oszi auszumessen, weiß das vielleicht jemand aus dem Kopf?
42 Takte für float und 84 Takte für double.

SCNR

von Pandur S. (jetztnicht)


Lesenswert?

Miss mit dem Oszilloscope nach. Es wird in den Milisekunden liegen. Also 
eher 42 x 42 Takte.

von Georg G. (df2au)


Lesenswert?

Die Antworten wären bestimmt zielführender gewesen, wenn du uns verraten 
hättest, um welchen Prozessor es geht und welchen Compiler du nimmst.

Eine Suche mit Google bringt als Beispiel

I wanted to multiply two float numbers af=15343E-34 and bf=-23474E21. I 
noticed that Keil compiler generates assembly code that needs 271 Clock 
Cycles (on a Silab C8051F121, accelerated 8051) to generate the product.

Oder etwas länglicher unter

https://www.silabs.com/Support%20Documents/TechnicalDocs/CIP-51.pdf

von Peter D. (peda)


Lesenswert?


von m.n. (Gast)


Lesenswert?

Fabian F. schrieb:
> Ich habe das Gefühl ewig, aber bevor ich mir die Mühe mache das mit dem
> Oszi auszumessen, weiß das vielleicht jemand aus dem Kopf?

Das "ewig" kannst Du gleich wieder streichen. Auf einem 20 MHz AVR 
dauert eine fdiv() ca. 20-30 µs. Eine int32-division ist nicht unbedingt 
schneller, sodaß man ruhig bei float bleiben und die hohe Dynamik nutzen 
kann. Das hat sich allerdings noch nicht weit herumgesprochen ;-)

Bei double-Werten waren es (soweit ich mich erinnere) rund 50-70 µs mit 
einem IAR-Compiler.

von Helmut L. (helmi1)


Lesenswert?

m.n. schrieb:
> Eine int32-division ist nicht unbedingt
> schneller, sodaß man ruhig bei float bleiben und die hohe Dynamik nutzen
> kann.

Ist aber auch klar, die float Division setzt ja nach der Normalisierung 
auf eine Intergerdivision auf. Das bisschen schieben davo und dahinter 
machen den Kohl auch nicht fett.

von m.n. (Gast)


Lesenswert?

Helmut L. schrieb:
> Ist aber auch klar, die float Division setzt ja nach der Normalisierung
> auf eine Intergerdivision auf. Das bisschen schieben davo und dahinter
> machen den Kohl auch nicht fett.

Mit dieser Ansicht gehörst Du aber zu einer Minderheit!
Die schreiende Mehrheit läßt selbst int32-Divisionen nicht zu - 
lediglich Schiebereien sind erlaubt ;-)

von Ingo L. (corrtexx)


Lesenswert?

Man bedenke auch, dass der GCC kein double kennt...

von Oliver S. (oliverso)


Lesenswert?

Nun ja, die Aussage ist dann doch etwas zu pauschal ;)

Der avr-gcc ...

Oliver

von Pandur S. (jetztnicht)


Lesenswert?

Int32 hat uebrigens 100 mal mehr Dynamik (10^9) wie float32. (10^6)

von Christopher B. (chrimbo) Benutzerseite


Lesenswert?

Oder D. schrieb:
> Int32 hat uebrigens 100 mal mehr Dynamik (10^9) wie float32. (10^6)

1000 (10^9 / 10^6) SCNR

von Peter D. (peda)


Lesenswert?

Oder D. schrieb:
> Int32 hat uebrigens 100 mal mehr Dynamik (10^9) wie float32. (10^6)

Selten so gelacht.

single: 1,175·10^−38 .. 3,403·10^38
Dynamik: 10^76

uint32: 1 .. 4,3·10^9
Dynamik: 10^9

von m.n. (Gast)


Lesenswert?

Peter D. schrieb:
> Selten so gelacht.

Mir sind dabei eher die Tränen gekommen :-(

von Ingo L. (corrtexx)


Lesenswert?

Peter D. schrieb:
> single: 1,175·10^−38 .. 3,403·10^38
> Dynamik: 10^76
Die Dynamik eines floats ist in der Tat kleiner als die eines uint32. 
Siehe https://de.wikipedia.org/wiki/Gleitkommazahl#Ausl.C3.B6schung

Dynamik != Wertebereich

Lothar hat das hier sehr schön beschrieben:
Beitrag "Re: Vorteil integer - float"

: Bearbeitet durch User
von Helmut L. (helmi1)


Lesenswert?

m.n. schrieb:
> Mit dieser Ansicht gehörst Du aber zu einer Minderheit!
> Die schreiende Mehrheit läßt selbst int32-Divisionen nicht zu -
> lediglich Schiebereien sind erlaubt ;-)

Die schreiende Mehrheit war wohl Einzelkind und hat nicht teilen 
gelernt, dann braucht auch ein uC es nicht zu koennen :=)

von Pandur S. (jetztnicht)


Lesenswert?

32bit float hat 5-6 signifikante stellen, wegen 23 bit Mantisse, 8 bit 
exponent, plus sign, oder aehnlich.

waehrend int32 9 signifikante stellen haben kann.

von W.S. (Gast)


Lesenswert?

Fabian F. schrieb:
> weiß jemand zufällig..

nee, nicht zufällig.

Also: Pro Mantissenbit ist eine Subtraktion in Mantissenbreite fällig 
und ggf. eine Restrückstellung oder alternativ deren Verschiebung auf 
die nächstkleinere Stelle, was in jeder Stelle eine zusätzliche 
Fallunterscheidung oder zwei zusätzliche Sprünge erfordert. Wieviele 
Maschinentakte die Subtraktion in 24 oder 48 Bit benötigt, hängt von der 
Architektur ab. Wie gut man den Rest hinkriegt, ebenfalls.

Dazu kommt noch die anschließende Normalisierung und 
Vorzeichenberechnung und das Zusammensetzen des Ergebnisses (Exponent 
über Bytegrenze verschieben und Vorzeichen einbauen).

Die Idee mit dem Oszi oder eben random Zahlen 1000x dividieren und per 
UART debuggen wäre wohl das Beste in diesem Fall.

W.S.

von Fabian F. (fabian_f55)


Lesenswert?

m.n. schrieb:
> Fabian F. schrieb:
>> Ich habe das Gefühl ewig, aber bevor ich mir die Mühe mache das mit dem
>> Oszi auszumessen, weiß das vielleicht jemand aus dem Kopf?
>
> Das "ewig" kannst Du gleich wieder streichen. Auf einem 20 MHz AVR
> dauert eine fdiv() ca. 20-30 µs. Eine int32-division ist nicht unbedingt
> schneller, sodaß man ruhig bei float bleiben und die hohe Dynamik nutzen
> kann. Das hat sich allerdings noch nicht weit herumgesprochen ;-)
>
> Bei double-Werten waren es (soweit ich mich erinnere) rund 50-70 µs mit
> einem IAR-Compiler.

Danke, wir verwenden auch IAR-Compiler, allerdings auf einem 8MHz-µC 
d.h. beim double komme ich dann schon so auf 150µs. Bei 6 
double-berechnungen pro Durchgang komme ich dann also schon auf 0,8ms, 
was sich mit den sporadischen Jitter-Phänomen im 1-ms-Timer decken 
würde.

Die Idee wäre es aud Uint64 umzusteigen und damit die Division komplett 
zu umgehen. Der Skalierungsfaktor ist dann immer >1, sprich 
Multiplikation...

von Peter D. (peda)


Lesenswert?

Ingo L. schrieb:
> Die Dynamik eines floats ist in der Tat kleiner als die eines uint32.

Was Du meinst, ist die Auflösung, d.h. die Anzahl signifikannter 
Stellen.
Dynamik ist aber das Verhältnis von kleinstem zu größtem Wert:

https://de.wikipedia.org/wiki/Dynamikumfang

von Georg (Gast)


Lesenswert?

Fabian F. schrieb:
> Die Idee wäre es aud Uint64 umzusteigen und damit die Division komplett
> zu umgehen. Der Skalierungsfaktor ist dann immer >1, sprich
> Multiplikation...

Entschuldige, aber das macht doch die ganze Diskussion überflüssig, 
natürlich verwendet man bei festen Werten immer eine Multiplikation 
anstelle der Division. Bei der Umwandlung z.B. von inch in cm durch 2,54 
zu dividieren ist ein unverzeihlicher Kunstfehler, selbstverständlich 
multipliziert man da mit dem Kehrwert von 2,54.

Georg

von m.n. (Gast)


Lesenswert?

Fabian F. schrieb:
>> Bei double-Werten waren es (soweit ich mich erinnere) rund 50-70 µs mit
>> einem IAR-Compiler.
>
> Danke, wir verwenden auch IAR-Compiler, allerdings auf einem 8MHz-µC
> d.h. beim double komme ich dann schon so auf 150µs.

Dann habe ich mich ja richtig erinnert.

Georg schrieb:
> Bei der Umwandlung z.B. von inch in cm durch 2,54
> zu dividieren ist ein unverzeihlicher Kunstfehler, selbstverständlich
> multipliziert man da mit dem Kehrwert von 2,54.

Wenn ich mit 2,54 multiplizieren will, dann mache ich das auch so. Ich 
bin doch nicht der Sklave meines µC!

von Sepp aus Hintertupfing (Gast)


Lesenswert?

Fabian F. schrieb:

> Ich habe das Gefühl ewig, aber bevor ich mir die Mühe mache das mit dem
> Oszi auszumessen, weiß das vielleicht jemand aus dem Kopf?

Wo hast du deinen Kopf ?

Fabian F. schrieb:

> Moin moin,

gut Nacht, gut Nacht

von Peter D. (peda)


Lesenswert?

W.S. schrieb:
> Die Idee mit dem Oszi oder eben random Zahlen 1000x dividieren und per
> UART debuggen wäre wohl das Beste in diesem Fall.

Warum so umständlich.
Einfach die Aufrufe mit nem HW-Timer messen und dann ne Weile durch den 
Simulator rasseln lassen. Min, Max, Mittelwert legt man in Variablen ab.

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.