Forum: Mikrocontroller und Digitale Elektronik Floating-Point Leistung mit Emulation


von Michael S. (kyromaster)


Lesenswert?

Wie hoch ist denn (geschätzt) die Floating-Point Leistung eines AVR in 
Relation zur Ganzzahlleistung, zum Beispiel bei Addition und 
Multiplikation?
So wie ich das verstehe muss das Ganze ja in Software emuliert werden.
Gibt es eigentlich Gründe dass in vielen Embedded Prozessoren keine 
Floating-Point Unit drin ist? Also einfach "das viele Anwendungen so 
etwas nicht brauchen" rechtfertigt das ja IMHO nicht ganz.

von Robert Teufel (Gast)


Lesenswert?

Der Grund: Kosten!  Ein FP-Unit ist viel komplexer als eine AVR CPU und 
somit viel groesser auf dem Chip. Groesse des Chip -> Preis
Also viele brauchen es nicht, wollen also nicht dafuer bezahlen -> ist 
nicht drauf.

Weiss nicht welcher Jahrgang Du bist aber es gab mal einen Float 
Coprozessor von Intel, den 8087 und spaeter den 80287, die waren jeweils 
um ein vielfaches teurer als die 8086 / 80286.

In der Emulation gibt es aber maechtige Unterschiede. Z.B. gibt es 
einfach Befehlssaetze (nicht AVR ;-) die Floatingpoint in Software recht 
gut unterstuetzen.  Ausserdem sind Floatingpointdaten VIEL breiter als 
8-bit, somit ist es fuer 16- oder 32-bit Prozessoren einfacher die 
Software Emulation zu berechnen.

Gibt ne Menge Optionen, ein paar Millisekunden warten mit dem AVR ist 
wohl die einfachste.

Gruss, Robert

von Postman (Gast)


Lesenswert?

>Weiss nicht welcher Jahrgang Du bist aber es gab mal einen
>Float Coprozessor von Intel, den 8087 und spaeter den 80287

Ach ja, die gute alte Zeit. Im Windows-Compiler konnte man damals 
einstellen, ob der Code mit dynamischer, statischer und gar keiner 
FP-Unterstützung erzeugt werden soll. Beim dynamischen, würde zur 
Laufzeit nachgeguckt, ob eine FP-CPU anwesend war. Ich weis bis heute 
nicht, wie das ging. Dann kamen aber die DX-Prozessoren und das Problem 
war gelöst :-)

von Fritz G. (Gast)


Lesenswert?

@Robert
Weiss nicht welcher Jahrgang Du bist, aber es gab mal einen Float
Coprozessor von AMD (AM9511), der sehr teuer war und mit seinen 2-4 MHz 
Ende der 70er berauschend schnell war. Ein paar Jahre später wurde die 
gleiche Geschwindigkeit mit dem Fast Floating Point Package von Motorola 
auf dem 68000 mit 8 MHz erreicht ....

> ... ein paar Millisekunden warten mit dem AVR ist wohl die einfachste.
Das muß nicht sein !

@Michael
Solange man mit 8bit-char oder 16bit-int Variablen auskommt, sind 
Ganzzahloperationen deutlich schneller, insbesondere die Multiplikation, 
da sie 8bit-weise von der CPU unterstützt wird. Die Division wird schon 
deutlich langsamer.
Ein Vergleich der Rechenzeiten ist erst bei 32bit-long in Bezug auf 
32bit-float sinnvoll. Für float auf einem 16 MHz AVR habe ich Zeiten von 
20-30µs im Kopf. Im Vergleich MUL32 zu FMUL32 ist MUL32 etwa 3 mal 
schneller, da hier wiederum die CPU ihre speziellen MUL-Befehle 
einsetzen kann. Bei DIV32 zu FDIV32 gibt es keine großen Unterschiede, 
da die Hauptarbeit durch Bitschiebereien erledigt werden muß: 32 Bit bei 
long und 24 Bit bei float (Mantisse).

Float hat den großen Vorteil, immer hohe Auflösung bei akzeptabler 
Geschwindigkeit zu bieten. Braucht man z.B. 1000 Operationen/Sekunde 
wird die CPU mit (nur) <5% belastet. Geschickt ist es, Divisionen durch 
Multiplikationen mit dem Kehrwert auszuführen (z.B. Skalierung von 
AD-Werten).

Die benötigte Codegröße für die Grundrechenarten und 
Vergleichsoperationen liegt bei guten Compilern unter 1K, um den 
Kritikern gleich den Wind aus den Segeln zu nehmen :-)

Vor längerer Zeit hat hier jemand etwas zu Rechenzeiten von FMUL/FDIV 
auf einem ARM7 berichtet: 1-2 µs. Sehr beachtlich.

von Michael S. (kyromaster)


Lesenswert?

Danke für die ausführliche Info :)
3 mal langsamer ist ja gar nicht so viel, ich hatte so mit 20mal 
langsamer oder so gerechnet.

von Peter D. (peda)


Lesenswert?

Michael Stather wrote:

> Also einfach "das viele Anwendungen so
> etwas nicht brauchen" rechtfertigt das ja IMHO nicht ganz.

Mö, viele MC-Anwendungen benutzen ja float.
Bloß sie brauchen es nicht sauschnell.


Peter

von rene (Gast)


Lesenswert?

Michael,
was willst du denn mit floating point ? So toll ist das gar nicht. Ein 
single precision float hat 32 bit, wovon 23 bit mantisse ist, was einen 
dynamischen Bereich von 8e6 betraegt. Den krieg ich auch mit 24bit 
integer. Der normale longint hat einen dynamischen Bereich von 4e9. Dazu 
muss man dann schon auf double gehen bei float. Und double auf einem 
AVR, falls ueberhaupt unterstuetzt, ist nochmals ein Stueck langsamer. 
Dazu ist anzumerken, dass auch mit Integern als fractional gearbeitet 
werden kann. Behalte den exponenten in Kopf, resp auf dem Papier.
Floating point haelt die Entwickler vom Denken ab. Sobald man sin, cos, 
exp moechte wird float extrem zeitaufwaendig. Da kann man oft was mit 
Polynom approximationen, Tabellen, Splines und dergl. arbeiten.

rene

von Michael S. (kyromaster)


Lesenswert?

Ich bin wirklich kein Profi was AVR angeht, bins halt von C++ aufm PC 
gewohnt einfach den float-Datentyp zu nehmen. Und für die Sachen die ich 
bis jetzt mit AVR gemacht habe hat die Rechenlsitung immer gereicht.
Meinst du mit "integer" dass man die Berechnung quasi mit integer-werten 
umsetzt (also ohne Compiler-Unterstützung)?

von Lupin (Gast)


Lesenswert?

nimm fixed point... ((int)(1.2*256)*x)>>8 = 1.2*x

von Lupin (Gast)


Lesenswert?

wobei x natürlich auch ein fixed point wert sein muss

von Johnny (Gast)


Lesenswert?

> nimm fixed point... ((int)(1.2*256)*x)>>8 = 1.2*x

Genau, das mach ich auch immer so falls möglich / sinnvoll.

Das heisst also konkret: (307 * x) >> 8
Dabei kann das >> 8 wahrscheinlich vom Compiler/CPU in einem Zyklus 
durch einen Kopierbefehl gemacht werden.

Es ist nur zu beachten, dass x * 307 keinen Überlauf verursacht, wenn 
das Ergebnis zu gross wird. Also ist auszurechnen, wie gross x für 
diesen Fall maximal sein darf und eventuell abfangen.

Sonst gehts auch kleiner, aber auch ungenauer:
z.B. (19 * x) >> 4 Das würde dann x * 1.1875 entsprechen.

von Lupin (Gast)


Lesenswert?

man rechnet am besten mit 64 bit. die ARMs können das sehr gut, ein AVR 
wohl eher weniger.

Wenn du nur 8.8 zahlen hast kannst du auch wunderbar mit 32 bit rechnen 
(also hast du dann 24.8) dann hast du weniger probleme mit dem überlauf. 
Oder halt 16.16 dann hast du zwar mehr präzision aber kannst im grunde 
nur 8.16 mit 8.16 im vollen integerbereich miteinander multiplizieren

von Michael (Gast)


Lesenswert?

Rene,

Irren ist menschlich, aber die Ansammlung Deiner Irrtümer muß ich leider 
als totalen Müll bezeichnen.

Nur soweit: Bereiche werden durch Unter- und Obergrenzen beschrieben. 
Bei 'float' ist dieser +/- 1.18e-38 bis +/- 3.39e+38.

Viel Spatz beim Approximieren, Tabellieren und Splinieren.

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.