Hallo,
ich entwickle grade ein eigenes kleines Board mit einem ARM7
Mikrocontroller. Ein FPGA soll da auch mit drauf, ich dachte an das
Modell EP2C8 von Altera.
Der FPGA wird hauptsächlich als IO-Baustein benutzt (er macht ne PWM und
steuert viele parallele IO-Ports).
Frage: da ich gerne floating point nutzen würde für gewisse
Berechnungen, dachte ich mir könnte man vielleicht im FPGA eine kleine
FPU integrieren? Der Mikrocontroller kann den FPGA über das externe
Speicherinterface ansprechen wie ein statisches RAM. Ich hab in den
Adressbereich gewisse register gemappt, sodass man z.B. die PWM
einstellen kann und dergleichen.
Frage: Wäre so eine FPU prinzipiell machbar? Könnt ihr mir dazu
vielleicht sogar ein paar Anregungen geben? Eine weitere Frage wäre
dann, wie ich das ganze in meinem Programmcode für den Mikrocontroller
so einbaue, dass es für den Compiler transparent ist. Sprich, wenn ich
folgendes Programmiere
float a, b, c;
a = 1.23;
b = 2.34;
c = a * b;
Dann soll der Compiler das nicht softwaremässig ausrechnen, sondern soll
meine FPU ansprechen, die das dann in Hardware macht.
Ist mein Vorhaben realisierbar?
Machbar ist das schon, die Frage ist ob es sich für solch ein Level
überhaupt lohnt.
Ich weiß nun nicht wie viele Takte der ARM7 für eine Multiplikation
bräuchte, aber selbst bei gleichem Takt von FPGA und Controller wären es
dann mindestens 2.
Bei Divisionen ggf noch viel mehr(kommt auf den Takt des ARM an).
Im compiler würde ich das über eine Funktion lösen, also mult(a,b) ->
welche dann eben die entsprechenden schreib und lesebefehle ausführt.
Eventuell kann man aber auch die Aktionen auf den Operator auftauschen,
da ich von ARM bzw den Compilern dazu jedoch nichts verstehe kann ich
dazu nichts sagen.
Also machbar auf jeden Fall, wirklich lohnen tut es sich im Allgemeinen
jedoch erst bei umfassenderen Berechnungen. Typischerweise Berechnungen
die im Gegensatz zum Controller parallelisiert werden können.
Ich denke, dass das schon beschleunigt, da ja floating point Operationen
nicht in 2 Takten erledigt sind. Das das ein Workaround ist... schon
klar. Aber unter den gegebenen Umständen ist die Lösung meiner Meinung
nach gut. Es sei denn, es kommen kaum solche Operationen vor. Dann ist
es den Aufwand wahrscheinlich nicht wert. Auch nicht, wenn die SW eh
genug Zeit hat, die Berechnungen zu erledigen.
Und machbar ist das sicher. Ein paar Register für die Werte und eines
für die Operationen. Status und Ergebnis kann dann in weiteren Registern
abgeholt werden.
Machbar ist das, ohne dass du etwas am Compiler ändern musst. Du
kompilierst den Code mit Floating-Point-Befehlen, fängst die undefined
instruction exceptions ab, und gibst die Arbeit da an den Coprozessor
ab. Auf diese Weise ist z.B. Soft-Floating-Point im Linux-Kernel
implementiert.
Hi
das ist dann aber sicher nicht mehr schneller als -msoft-float.
- Exception tritt auf
- Eintritt in den Handler
- Setzen von FPGA Registern (da extern geht das auch nicht beliebig
schnell)
- Warten bis das FPGA soweit ist
- Auslesen des Ergebnis
- Laden der internen Register mit dem Ergebnis
- Austritt aus dem Handler
Floating point in Software ist übrigens gar nicht so schlimm wie man
sich das vorstellt.
Matthias
Andreas Schwarz schrieb:
> Machbar ist das, ohne dass du etwas am Compiler ändern musst. Du> kompilierst den Code mit Floating-Point-Befehlen, fängst die undefined> instruction exceptions ab, und gibst die Arbeit da an den Coprozessor> ab.
Ist zwar sehr clever, führt aber dazu, dass das alles noch langsamer
wird. Das endet dann in einer großen switch-case Anweisung im undef
Handler, die auch erstmal bearbeitet werden will.
Wenn eine FPU unbedingt nötig sein sollte, dann sollte man sich auch
einen Prozessor mit FPU gönnen. Alles andere ist gebastelt. Die Frage
ist, ob der OP das machen will weil's Spaß macht und scheinbar elegant
ist, oder weil ein dringender Bedarf besteht ("Software läuft nicht, da
der Prozessor mit floating point Berechnungen voll ausgelastet ist und
Festkomma nicht in Frage kommt").
Auf jeden Fall eine Kosten-Nutzen Analyse durchführen.
Gruß
Marcus
http://www.doulos.com/arm/
Ja, viel kann man sich von dieser Exception-Lösung nicht erwarten.
Irgendwo gibt es einen Benchmark der "direktes" Soft-Float mit
Soft-Float per Exception vergleicht; letzteres ist um eine Größenordnung
langsamer, wenn ich mich richtig erinnere.
>> Wenn eine FPU unbedingt nötig sein sollte, dann sollte man sich auch
einen Prozessor mit FPU gönnen
Diese Ansicht könnte man auch unbegrenzt weiter betreiben.
Dann wären plötzlich Grafikkarten auch sinnlos und Asics für Mpeg
braucht wohl auch niemand mehr, kaufe man doch sich einfach einen
Controller der schnell genug dafür ist.
Ganz nach dem Motto : sollen sie doch Kuchen essen !
Weiß auch nicht was an einem CoProzessor-Konzept Gebastel ist. Viel mehr
ist das doch Standard weil sinnvoll. Man laste jeden Chip mit der Art
von Funktionen aus für die er gemacht ist und alles wird gut.
Der FPGA ist beim OP nunmal vorhanden deswegen spricht auch nichts
dagegen den zu benutzen wenn es wirklich zu einem Speedup führt.
Hatte zwar eigentlich vermutet der ARM7 würde das auch recht schnell
können aber dem ist wohl nicht so und dann lohnt es sich allemal.
Sonderlich viel Aufwand ist das nun wirklich nicht wenn die ganze
Kommunikation eh schon steht.
Tut mir Leid, ich muss mich so stark dafür einsetzen. Dieses
Thema(Auslagerung von rechenintensiven Aufgaben auf einen FPGA) ist der
Grund warum ich überhaupt zu meinen Lieblingen gekommen bin :)
Hallo,
sorry dass ich mich so spät erst wieder melde. Ich war unterwegs...
Cool, so viele Beiträge!
Also, der FPGA ist am externen Memory Interface des ARM7 angebunden über
einen 16 Bit breiten Bus. Der ARM läuft mit 80 MHz, und kann auch mit
dieser Geschwindigkeit auf den Bus zugreifen, ich denke das sollte nicht
das Problem sein.
Und genau so, wie das weiter oben beschrieben wurde, wollte ich das auch
machen: über die UNDEF-Exception. Eigentlich hätte ich erwartet, dass
das schneller ist, als in Software zu rechnen, nun bin ich ein bisschen
erstaunt, dass dem nicht so sein soll? :-O
Eine weitere denkbare Lösung wäre wie folgt:
Man kompiliert mit Sofware-floating Point. Der Compiler sucht dann ja
nach bestimmten Funktionen; wenn ich im Code zum Beispiel eine
float-Addition habe, dann generiert der Compiler an dieser Stelle dann
in wirklichkeit nicht das
c = a * b;
sondern das:
c = fmul(a, b);
Wobei fmul eine Funktion ist, die softwaremässig zwei float-Zahlen
addiert.
Wenn ich jetzt das Symbol fmul auf meine eigene float-addition
'verbiegen' würde, dann hätte ich da bereits eine fertige Funktion, die
die beiden Operanden bekommt, diese nur noch in den FPGA schaufeln muss
und die Ergebnisse dann wieder ausliest.
Ich wage mal zu behaupten, dass dies allemal schneller wäre, als
softwaremässig zu rechnen, oder täusche ich mich da?
Des weiteren frage ich mich natürlich, ob mein doch schon relativ
kleiner FPGA zumindest für eine bescheidene FPU reicht. Wenn er
wenigstens dividieren könnte, wäre das schon eine ziemliche
Erleichterung, denn der ARM7 hat keine Instruktion für Dividieren.
Warum ich das machen will:
Es soll nur ein Experiment sein. Schauen ob es geht, und ob es eine
Verbesserung beim Rechnen bringt. Es ist also nur eine Spielerei, aber
wie bereits korrekt gesagt wurde:
Der FPGA sitzt eh schon auf dem Board, und er ist nur recht wenig
ausgelastet (ein paar IOs, ein paar PWMs). Da könnte man doch noch was
machen mit! :-)
Hübsche Tabelle über die Performance von ARM7 bei Fliesskommrechnung bei
48MHz, für deine 80MHz entsprechend skalieren:
http://www.smxrtos.com/ussw/gofast/gofast_arm_cwk.htm
Jetzt rechne mal zusammen, wieviel Takte für die Operandenübertragung
zum FPGA draufgehen, plus Overhead der Funktion. Dazu kommt dann noch
eine vom Aufwand der FPGA-Implementierung abhängige Anzahl Takte (ein
kombinatorischer Multiplier frisst recht viel Platz). Dann kriegt du
eine Vorstellung davon, ob sich das lohnt.
Eine FPU wird in den seltensten Faellen benoetigt. Wer brauch denn schon
einen dynamischen Bereich von 10^306 fuer einen Single. Ein Int32 hat
aber mehr signifikante Stellen wie ein Single.
Mini Troll schrieb:
> Eine FPU wird in den seltensten Faellen benoetigt. Wer brauch denn schon> einen dynamischen Bereich von 10^306 fuer einen Single.
Welches single precision format hat diesen Exponentenbereich? IEEE 754
jedenfalls nicht.
Gerd schrieb:
> Wenn ich jetzt das Symbol fmul auf meine eigene float-addition> 'verbiegen' würde, dann hätte ich da bereits eine fertige Funktion, die> die beiden Operanden bekommt, diese nur noch in den FPGA schaufeln muss> und die Ergebnisse dann wieder ausliest.
Das ist auf jeden Fall der Weg den es zu gehen gilt. Sobald du das über
Exceptionhandling machst wird laaaaangsam. Wenn du wissen willst was
dein FPGA-Programm dann schlagen soll schau mal hier:
http://gcc.gnu.org/viewcvs/trunk/gcc/config/arm/ieee754-sf.S?revision=148210&view=markup
Das ist die Softfloat Implementierung des GCC
> Ich wage mal zu behaupten, dass dies allemal schneller wäre, als> softwaremässig zu rechnen, oder täusche ich mich da?
Wie schnell kann dein FPGA nach dem Laden der Register das Ergebnis
berechnen? In einem einzelnen Takt dürfte das ja auch nicht machbar
sein.
> Warum ich das machen will:> Es soll nur ein Experiment sein. Schauen ob es geht, und ob es eine> Verbesserung beim Rechnen bringt.
Dann mach es. Du wirst dabei viel lernen. Das es wirklich (deutlich)
schneller wird denke ich nicht aber das soll dich nicht abhalten.
Evtl. lohnt sich aber ein Blick eine Ebene höher. Was machst du mit den
Floatberechnungen? Lohnt es sich evtl. den ganzen Algorithmus auf das
FPGA auszulagern?
Matthias
Hallo,
also der FPGA bekommt seinen Takt von einem 50 MHz Quarzoszillator.
ABER! er hat zwei PLL's drin. Wenn man möchte, könnte man dann doch
damit den Takt auf sagen wir mal 200 MHz vervielfachen, und dann mit
diesem schnelleren Takt die Berechnungen durchführen. Oder nicht? Das
sollte dann ja auch nochmal schneller sein.
Dass es sich lohnt vom Aufwand her habe ich schon von Anfang an
bezweifelt, aber versuchen möchte ich es trotzdem. Wie Matthias gesagt
hat - weil ich dabei einiges zu lernen beabsichtige. Und wer weiss,
vielleicht kann man das ja auch brauchen?
Frage:
Kennt jemand eine gute FPU-Implementierung auf einem FPGA? Auf Opencores
habe ich bereits geschaut. Gibts noch mehr?
Gerd schrieb:
> ABER! er hat zwei PLL's drin. Wenn man möchte, könnte man dann doch> damit den Takt auf sagen wir mal 200 MHz vervielfachen, und dann mit> diesem schnelleren Takt die Berechnungen durchführen. Oder nicht?
Das hängt etwas davon ab, wie deine FPU arbeitet. Wenn du nicht genug
Platz für einen mindestens partiellen kombinatorischen Multiplizierer
hast, dann muss der Takt so schnell werden wie möglich und wie die
internen Laufzeiten zulassen(!). Und es wird dann trotzdem nicht
reichen.
Wenn du andererseits einen solchen drin unterbringst, dann wird dessen
Performance nicht primär vom maximal theoretisch möglichen Takt des
FPGAs bestimmt, sondern massgeblich von der Durchlaufzeit des CSA-Trees.
Iulius schrieb:
> Diese Ansicht könnte man auch unbegrenzt weiter betreiben.>> Dann wären plötzlich Grafikkarten auch sinnlos und Asics für Mpeg> braucht wohl auch niemand mehr, kaufe man doch sich einfach einen> Controller der schnell genug dafür ist.
Kommt auf die Anwendung an. Ich kann durchaus nachvollziehen, weshalb
jemand das unter Umständen lieber mit Hardware von der Stange erledigen
möchte.
> Ganz nach dem Motto : sollen sie doch Kuchen essen !
Wenn der Kuchen letztlich günstiger ist, warum nicht.
> Weiß auch nicht was an einem CoProzessor-Konzept Gebastel ist.
Weil eine professionelle Anwendung verlangt, mehr oder weniger
umfangreiche Doku zu lesen (IEEE754), zu verstehen(!), das Verstandene
umzusetzen, Dokumentation zu erstellen, die korrekte Funktion zu
verifizieren, usw.
Bei einem Controller mit FPU hat sich die Arbeit schon jemand anderes
gemacht. Schneller als die FPGA Lösung ist es sowieso.
> Sonderlich viel Aufwand ist das nun wirklich nicht wenn die ganze> Kommunikation eh schon steht.
Nun ja...
> Tut mir Leid, ich muss mich so stark dafür einsetzen. Dieses> Thema(Auslagerung von rechenintensiven Aufgaben auf einen FPGA) ist der> Grund warum ich überhaupt zu meinen Lieblingen gekommen bin :)
Gegen auslagern kritischer Funktionen ist ja nichts einzuwenden. Nur
muss man eben sorgfältig abschätzen ob man unterm Strich, unter
Einbeziehung des zweifellos höheren Entwicklungsaufwands, was davon
hat. In einem kommerziellen Projekt würde ich bei dieser
Anwendungsbeschreibung eher davon abraten. Für ein Proof-of-Concept,
oder eine Spielerei wie in diesem Fall ist das allemal eine nette
Aufgabe.
Gruß
Marcus
http://www.doulos.com/arm/
Ja wie ich oben schon geschrieben habe : ich hielt es ursprünglich auch
nicht für so sinnvoll weil ich nicht vermutet habe das sich eine
Multiplikation überhaupt signifikant beschleunigen ließe.
Wenn ich mir aber die smxrtos seite ansehe und der arm7 für eine
multiplikation >1µs benötigt, dann sehe ich da doch die möglichkeit das
zu schaffen.
Der einzig wirkliche Aufwand ist doch dabei die Kommunikation.
Der ep2c8 hat 36 multiplier eingebaut, also kann der das ziemlich fix.
Habs grad mal probiert, der standardwizard schafft selbst bei 64bit
floating point eine multiplikation in ~55ns, also mit nicht ganz 20mhz.
Damit sind auch nur 50% der internen multiplier belegt sowie 11% der LE.
(man könnte also sogar 2 einbauen)
Single precion sind es sogar fast 40mhz die erreicht werden bei ~4%(20%
mult) FPGA Belegung.
Selbst das (wizard-und-einmal-hingeklickt-Lösung) ist, zumindest im
vergleich zu oben verlinkter Tabelle, mehr als 20mal so schnell.
Wenn man also die Kommunikation in entsprechender Zeit schafft, dann
spricht nichts dagegen.