Messwerte (float) komprimieren
-
Hallo,
ich möchte Messzeitreihen komprimieren. In der Zeitreihe liegen gemessene Werte mit einem Status ab. Der stark vereinfachte Kern der Routine sieht etwa so aus:
struct Messwert{ float wert; char status; }; struct Messzeitreihe{ unsigned int id; string kurztext; Messwert *zeitreihe; }; int main(){ Messwert *mw = new Messwert[999]; Messzeitreihe *mzr = new Messzeitreihe; mzr->zeitreihe = mw; // Hier werden die 1000 Messwerte eingetragen. Zum Beispiel... // mzr->zeitreihe[0].wert = 4711.0815; // mzr->zeitreihe[0].status = 01; // ... delete[] mw; delete mzr; return 0; }Dummerweise habe ich mehrere tausend Messzeitreihen mit mehreren hundert Messwerten. Um die Daten im Hauptspeicher zu halten muss ich sie komprimieren. Wie kann ich das tun? Die meisten mir bekannten Komprimierungsverfahren komprimieren INTEGER aber nicht FLOAT!
Gruß,
B!
-
BitShift schrieb:
Dummerweise habe ich mehrere tausend Messzeitreihen mit mehreren hundert Messwerten. Um die Daten im Hauptspeicher zu halten muss ich sie komprimieren. Wie kann ich das tun? Die meisten mir bekannten Komprimierungsverfahren komprimieren INTEGER aber nicht FLOAT!
Ich weiß nicht wie komplex das bei dir am Ende ist, aber kämde da nicht ein reinterpret_cast auf int infrage um das ganze dann zu Komprimieren?
-
Du kannst den verwendeten Arbeitsspeicher reduzieren, wenn statt der std::string-Klasse einen pointer auf char (oder bei vorher bekannter Groesse) ein definiertes Array of Char verwendest.
Im Normalfall macht das den "Kohl nicht fett", bei einer grossen Anzahl von Daten kann das entscheidend sein. Es hat auch positive Auswirkungen auf die Laufzeit.
-
abgesehen vom hauptproblem, daß anscheinend 1000 Messzeitreihen 1000000 Messwerte haben und bei deinem prog 1000 Messzeitreihen 1000 haben, kannste vermutlich floats fein reduzieren, indem du ihnen die mantisse beschneidest und wo wir schonamal dabei sind, den exponenten auch beschneidest. realistisch ist es, damit von 4 auf 3 bytes zu kommen, ohne kompletten unfug zu treiben.
stärkeres packen ist immer möglich, wenn man weiß, wie die daten vermutlich verlaufen. aber nicht viel stärker. und von den daten wissen wir hier leider gar nix. und besondere packraten, wie eins-zu-fünf bei mp3 kannste eh nicht erhoffen, fürchte ich. das müßte schon ein irrer zufall sein, daß du bereits weißt, daß die werte einer foobarfunktion folgen und du nur die abweichungen auswerten willst. vielleicht will man nur ln(f(x)) statt nur f(x) respektive es interessieren einen nur die kleinen werte genau und die großen sind, ach da kommt nicht drauf an. dann kannste logarithmieren und dann als int mit weniger bits speichern.
aber eigentlich meine ich, daß du sowas echt nicht packen solltest. schau, wie du an mehr speicher kommst.
-
Was mir da noch einfallen würde wäre einlesen, und sobald ne gewisse Masse da ist binär in ne Datei rausschreiben, und nen Sprungpunkt setzen das du sie wiederfindest. Das würde deinen Speiche rzu lastend er Geschwindigkeit entlasten, falls sowas für dich in Frage käme.
-
Ich kann Volkard nur 100% zustimmen.
Wenn ich nix genaueres als bloss das Wort "Messwerte" weiss, dann schätze ich die Chancen mal ziemlich schlecht ein, dass man da grossartig was komprimieren kann. Die meisten Messwerte haben die unangenehme Eigenschaft ziemlich verrauscht zu sein, und die Rauschkomponente kannst du schonmal garnicht komprimieren.
Davon abgesehen...
Wieviel Hauptspeicher hast du denn? Und wieso willst du mehrere Messreihen im Speicher halten? Wäre es nicht möglich das Programm auf einem normalen PC laufen zu lassen, wo genug Speicher für ein paar wenige Millionen floats zur Verfügung steht?----
Eine klitze-kleine Änderung wird dir vermutlich schonmal > 1/3 Speicher einsparen:
/* struct Messwert{ float wert; char status; }; */ struct Messzeitreihe{ unsigned int id; string kurztext; // Messwert *zeitreihe; float *werte; char *statussen; };Warum? Wegen dem sog. "structure packing".
Der eine std::string pro Reihe tut vermutlich nicht weh, da du ja kaum so wahnsinnig viele Reihen haben wirst (1000 Strings sind ja "nichts").