Hochperformante Routine für 16 Bit Gleitkomma (Minifloats) gesucht
-
Guten Tag zusammen,
die meisten µController haben "nur" 16 Bit Zahlenformate und rechnen in einem Takt alle arithmetischen Ganzzahloperationen durch, was auch meistens ausreicht.
Wer nun aber mit höherer Präzision (ich) rechnen lassen will kauft sich gefälligst einen DSP, der kann Float rechnen. Natürlich in Echtzeit, pro Takt. Genau diese Anforderung ist mir aber egal. Die Berechnung eines Float kann mir auch 100 Taktzyklen in Anspruch nehmen. Hauptsache irgendwie 16 Bit...
Frage: Gibt es auch eine Bibliothek für die Emulation von 16 Bit Gleitkomma Operationen auf einem µC?
Ich hab zwar net viel Hoffnung aber evtl. gibt´s ja bei Euch jmd. der was weis.
Grüßle
-
Darf ich fragen warum es minifloats sein müssen? Reicht dir Fixpunktarithmetik nicht aus?
-
Ich rate dir bei dem Hersteller des Mikrokontrollers mal nachzufragen. Denn ich weis ehrlich gesagt nicht, ob es eine allgemeine Bibliothek für eine breite Palette von Mikrokontrollern gibt.
Mikrokontroller sind spezialisierte Hardware, und dementsprechend wäre eine solche Bib auch spezialisiert. Ich kenne Controller, deren lesender Zugriff auf eine Eingangs-Addresse eine andere Adresse wiederspiegelt als der schreibende Zugriff auf die Eingangs-Addresse. Auch erlauben manche Controller keine Pointer, sondern nur Handles, ...
-
Bitte ein Bit schrieb:
Auch erlauben manche Controller keine Pointer, sondern nur Handles, ...
im ernst? welcher?
-
Die Bezeichnung kenne ich leider nicht. Ich weis bloß dass ich in naher Zukunft auf ihm programmieren werden.
Und auf diesem Controller wird ein Mini-Kernel verwendet, welcher eine Speicherverwaltung mit Relokation benutzt. Soll heißen, Teile des RAMs können zu Defragmentierungszwecken verschoben werden und zwar unabhängig von dem aktuell laufenden Program. Und damit können Pointer durch eine solche Aktion ungültig werden.
-
Bitte ein Bit schrieb:
Soll heißen, Teile des RAMs können zu Defragmentierungszwecken verschoben werden und zwar unabhängig von dem aktuell laufenden Program. Und damit können Pointer durch eine solche Aktion ungültig werden.
irres ding. fast schon 'ne virtual machine, ne? java macht es auch so, deswegen z.b. hat java auch keine pointer. poste doch mal etwas mehr infos über dieses system. würde mich echt interessieren.
-
Ok, ich probiere es mal.
Das Ganze ist ein Thema des Betriebssystems bzw. genauer gesagt der Speicherverwaltung, also dem Teil welchem Malloc und Co die allokierten Speicherblöcke angibt.
Nehmen wir dazu mal einen fiktiven, einfachen Rechner als Beispiel. Das Beispiel ist absichtlich abstrakt gewählt, also bitte nicht meckern, wenn es ein wenig unrealistisch ist. Der Rechner soll über einen 100 Byte großen RAM sowie einen 4 kHz Prozessor verfügen. Der Speicher lässt sich über die Adressen 1-100 direkt ansprechen. (Und alleine daran ist das Beispiel ein wenig unrealistisch, denn man brächte mindestens 7 Bit um den Speicher zu adressieren, was auf einen 8 Bit Prozessor hinauslaufen würde. Deswegen verwaltet man Speicher gerne in Blöcken, aber das ist momentan nicht unser Problem.)
Das Problem lässt sich nun relativ einfach beschreiben. Der Benutzer geht hin und reserviert nacheinander 100 Mal einen 1 Byte großen Speicherblock. Danach will der Benutzer einen 2 Byte großen Block im RAM speichern. Also löscht er den Speicherblock 2 und 5, weil er diese nicht mehr benötigt. Doch dummerweise kann er trotzdem die 2 Bytes nicht abspeichern, da keine 2 Byte großen, zusammenhängenden Speicherblöcke frei sind.
-------- 0x01 | Data | -------- 0x02 | | -------- 0x03 | Data | -------- 0x04 | Data | -------- 0x05 | | -------- 0x06 | Data | -------- ...
Eine Lösungsmöglichkeit wäre es die freien Speicherblöcke 2 und 5 aneinander zu schieben bzw. den Speicherblock 3 in den Speicherblock 2 zu kopieren, den Speicherblock 4 auf den Speicherblock 3 zu kopieren und den Speicherblock 4 zu löschen. Doch dazu müssen alle laufenden Programme, welche auf die Speicherblöcke 3 und 4 zugreifen, aktualisiert werden dass die Speicheraddressen sich geändert haben.
Eine Lösung dazu ist die Verwendung einer Tabelle, welche Datenblöcke auf Speicheradressen mapped. Der Sinn dahinter ist nun folgender: Jedes Programm greift nur über Datenblock-IDs (Handle) auf den Speicher zu. Ein fiktives Malloc() würde also nur eine Datenblock-ID zurückgeben. Ein Zugriff auf den Speicher würde über Funktionen wie "Byte Read(ID)" und "void WriteByte(ID, Byte)" laufen. Diese würden die ID mittels der Tabelle in eine Speicher-Adresse umwandeln und dann auf den Speicher zugreifen. Wenn nun ein Programm durch eine Speicheranfrage eine Verschiebung des Speichers verursacht, aktualisiert die Speicherverwaltung automatisch die Tabelle, so dass die Programme dadurch auf dem aktuellen Speicherstand bleiben.
Datenblock-ID (Handle) | Speicheradresse 1 | 0x01 3 | 0x03 -> Nach Verschiebung: 0x02 4 | 0x04 -> Nach Verschiebung: 0x03 6 | 0x06
Und das war schon eine grobe Idee der Speicher-Relakation. Ich habe hier noch einige Dinge wie Multitasking oder Laufzeitbetrachtungen außer Acht gelassen, welche die Sache durchaus kompliziert machen kann. Denn wie verhindere ich beispielsweise dass während ein Programm auf Speicherblock X zugreift, die Speicherverwaltung diesen Block zwischenzeitlich verschiebt ? Oder wie beeinflusst die Speicher-Verschiebungen Echtzeitanforderungen ?
-
^^man dankt. das ist aber sowas wie ein betriebssystem ne? ich hatte ursprünglich verstanden, dass der prozessor so arbeitet.
Bitte ein Bit schrieb:
Denn wie verhindere ich beispielsweise dass während ein Programm auf Speicherblock X zugreift, die Speicherverwaltung diesen Block zwischenzeitlich verschiebt?
entweder über virtuellen speicher, so dass zugriffe gleich mit-umgerechnet werden (ist ohne hardwareunterstützung aber irre langsam) oder programme können ihre speicherhandles 'locken', aber dann hast du nix besseres als malloc/free. oder sämtliche speicherzugriffe ausserhalb von lokalen variablen sind verboten, dann müssen die programme über spezielle read/write funktionen gehen.