gzopen() auf vector<uint8_t> anwenden.

Design Patterns, Erklärungen zu Algorithmen, Optimierung, Softwarearchitektur
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Antworten
Walker
Beiträge: 42
Registriert: 28.07.2017, 08:58
Alter Benutzername: Walker

gzopen() auf vector<uint8_t> anwenden.

Beitrag von Walker »

Hintergrund:
Ich habe viele Meshdaten die seit Jahrzehnten in eigenen Filetypen hinterlegt sind. Dieses sind quasi ZIP Files. Beim Lesen werden diese komplett in den Speicher geladen und da quasi entpackt und der entpackte Stream dann verarbeitet. Gut und schnell. Mit dem Nachteil (wir sind noch 32Bit & Windows unterwegs) das man bei großen Files natürlich kurzzeitig extra Speicher benötigt (gezippte und entzipped im Speicher).

Ich experimentiere etwas mit den gzip Funktionen. Also die Daten wie beim normalen FILE mit gzopen, gzwrite, gzread zu lesen. Gzip kümmert sich um das Packen/Entpacken und hat nur einen etwa 3MB Puffer Overhead (soweit ich gelesen hatte). Das klappt super, ausser das es langsamer läuft wie die ZIP Variante. Wohl wegen der kleinen Happen beim Lesen.

Daher die Idee ob man nicht das FILE als Byte (uint8_t) Daten komplett lesen kann (geht ja sehr schnell) und dann im Speicher den Stream mit gzip liest. Quasi Memory Cache des Files.

Code: Alles auswählen

ZEXTERN gzFile ZEXPORT gzopen  OF((const char *path, const char *mode));
gzopen nutzt aber direkt den Filepath und hat dann einen Zeiger aus "FILE" mit dem es weiter arbeitet.

Das Ziel wäre das man die kleinen Files oder bei genug Speicher mit der schnellen Variante liest und nur große Files bei Speichermangel in Häppchen verarbeitet.

GGf. hat ja jemand eine Idee oder Suchbegriff wie man sowas kombinieren kann. Auch eine Alternative zu gzip wäre ja denkbar wenn diese robust wäre.
Benutzeravatar
Schrompf
Moderator
Beiträge: 5047
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: gzopen() auf vector<uint8_t> anwenden.

Beitrag von Schrompf »

Deine Einleitung klingt, als hättest Du bisher was Anderes zum Entpacken benutzt als gzip. Nimm doch einfach das wieder?

Für mich stellt sich dann noch die Frage, was Du erreichen willst. Willst Du Speicher sparen? Den entpackten Mesh brauchst Du ja am Ende am Stück, oder Du kopierst ihn während des Entpackens portionsweise gleich in die GPU. Das wäre die Methode zum Speichersparen, ist zwar langsamer, aber dafür schmal und kann mit vorallokierten Scraps arbeiten.

Willst Du möglichst schnell das File als Bytes vorliegen haben? Dann öffne das File mit CreateFile() und schieb das Filehandle in MapViewOfFileEx(). Dann hast Du den FileContent im Speicher, und ganz nebenbei ist es die schnellstmögliche Methode, Daten von der Platte in den Prozess zu kriegen. Hat sogar noch ein paar Perks, falls Du riesige Files öffnen willst, aber Du bist ja noch auf Win32, da sind dem "riesig" enge Grenzen gesetzt.

Die meisten Archiv-Libs, die ich kenne, haben auch ein OpenFromFileInMemory() oder so... vielleicht ist Deine Wunschfunktion nur eine Seite weiter in der Doku. Hab aber nicht selbst gegoogelt.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Walker
Beiträge: 42
Registriert: 28.07.2017, 08:58
Alter Benutzername: Walker

Re: gzopen() auf vector<uint8_t> anwenden.

Beitrag von Walker »

Die Mesh-Daten müssen noch vielfältig verarbeitet werden. Direkt in die GPU ist daher nicht. Wir nutzen noch Ogre3D für den Kontext.
Die Sachen gucke ich mir mal an (MapView...).
Das Alte (ZIP und ostream ..) und das neue (GZIP, File) kann ich nicht zusammen nutzen. Ich muss je nach benutzten Speicher die Low-Memory Variante nehmen oder die Schnellste, wenn möglich. Ich will da nicht verschiedene Möglichkeiten implementieren die Daten zu lesen.
Benutzeravatar
Schrompf
Moderator
Beiträge: 5047
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: gzopen() auf vector<uint8_t> anwenden.

Beitrag von Schrompf »

Dann nimm das FileMapping und entpacke daraus mit dem ZIP, was Du genannt hast. Du hast keinen echten Speichermehrbedarf (READONLY-FileMappings sind wirklich nur MMU-Tricks mit OS-Rückhalt) und der Block ist wieder weg, sobald Du das File wieder schließt. Und entpacken kannst Du daraus im Ganzen oder Portionsweise, ganz wie es Dir behagt.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Schrompf
Moderator
Beiträge: 5047
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: gzopen() auf vector<uint8_t> anwenden.

Beitrag von Schrompf »

Addon: wir haben auf Arbeit libarchive, ne wahrhaft antike Lib, aber die öffnet alles Mögliche, aus dem RAM oder direkt ausm File.

Sie ist nur leider auch antik in der Hinsicht, dass sie globalen State hat, den sie nicht dokumentiert. Wenn ich aus mehreren Threads heraus versuche, das selbe File mehrfach zu öffnen und jeweils andere Teile zu extrahieren, hängt es z.B. bei tar.xz in nem Deadlock. Tja. Fixen werde ich das nicht mehr. Und für ZIP geht alles, auch Files >2GB. Andere Libs, die wir benutzten, scheitert dagegen manigfaltig an der 2GB bzw. 4GB-Grenze.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Walker
Beiträge: 42
Registriert: 28.07.2017, 08:58
Alter Benutzername: Walker

Re: gzopen() auf vector<uint8_t> anwenden.

Beitrag von Walker »

Schaue ich mir an. Danke.
Antworten