Seite 1 von 1

Effizientes Einlesen v. Binärdaten in Struktur(en)

Verfasst: Sa Nov 06, 2021 5:13 pm
von Leverator
Hallo zusammen,
ich habe heute lange versucht, eine effiziente Möglichkeit zu finden, Daten aus einer Binärdatei in eine Struktur (hier: std::vector< std::vector< std::vector<uint8_t> > > ) einzulesen.
Ich bin damit gescheitert und lese nun Byte für Byte die Datei ein und fummel mir die Struktur wie folgt zusammen:

Code: Alles auswählen

            data.clear();
            std::cout << "Loading. " << std::endl;
            for( uint32_t z=0; z<dimZ; z++ ) {
                std::vector< std::vector<uint8_t> > tmpY;
                for( uint32_t y=0; y<dimY; y++ ) {
                    std::vector<uint8_t> tmpX;
                    for( uint32_t x=0; x<dimX; x++ ) {
                        uint8_t tmpData = 0;
                        if( format == "uint8_t" ) {
                            // Daten aus der Datei in den Vector schreiben.
                            tmpData = testFile.get();
                            tmpX.push_back(tmpData);
                        }
                    }

                    tmpY.push_back( tmpX );
                    tmpX.clear();
                }
                data.push_back( tmpY );
                tmpY.clear();
            }
            
        }
Darum meine Frage in die Runde:
Wer kennt eine effiziente Möglichkeit, die Struktur entsprechend aus den Daten der Datei anzulegen?
Ich hätte ehrlich gesagt erwartet, dass es eine Möglichkeit gibt, in C++ die einzulesende Struktur parametriert zu definieren und dann mit einem Befehl die Informationen in das RAM zu jagen (z.B. über DMA).
Die definierte Struktur würde sich dann wie eine Schablone auf die Daten legen.

Wer mag helfen?

Viele Grüße,
Lev

Re: Effizientes Einlesen v. Binärdaten in Struktur(en)

Verfasst: Sa Nov 06, 2021 9:51 pm
von Xin
Leverator hat geschrieben:
Sa Nov 06, 2021 5:13 pm
Hallo zusammen,
ich habe heute lange versucht, eine effiziente Möglichkeit zu finden, Daten aus einer Binärdatei in eine Struktur (hier: std::vector< std::vector< std::vector<uint8_t> > > ) einzulesen.
Ich bin damit gescheitert und lese nun Byte für Byte die Datei ein und fummel mir die Struktur wie folgt zusammen:
Also ich sehe keine Chance, die äußeren Vektoren laden zu lassen, solange Du kein ORM-System benutzt. C++ bietet kein ORM an. Ich habe mir eins geschrieben, was aber std::vector nicht unterstützt, sondern nur eigene Datencontainer.

Zu erklären, dass man "mehrere von mehreren" hat, ist mir bzgl. Datenstrukturen Richtung Persistenz sonst nichts bekannt. Vielleicht kommt da noch was, ich bin da aber nicht im Bilde, was da zukünftig geplant ist. Ich habe mein ORM-System mal jemanden erklärt, der bei Boost aktiv ist, vielleicht kommt aus der Ecke ja mal was.
Ein Binärformat musst Du ansonsten aber nunmal von Hand erklären.
Leverator hat geschrieben:
Sa Nov 06, 2021 5:13 pm
Darum meine Frage in die Runde:
Wer kennt eine effiziente Möglichkeit, die Struktur entsprechend aus den Daten der Datei anzulegen?
DimX solltest Du mit read lesen können.
Du bereitest zuerst den Vektor auf die Größe vor mit reserve, so dass der Datenbereich des inneren Vektors entsprechend dimX Einträge fassen kann.
An der Stelle wird es jetzt ein wenig heikel. Wenn Du Dir beim Vektor mit front() die Referenz auf das erste Element holst, kannst Du die Adresse davon nehmen, das ganze als Ziel für istream::read verwenden.

Das ist prinzipiell nicht unbedingt definiertes Verhalten, müsste aber etwas effizienter funktionieren.

Offiziell gehen würde im Prinzip nur in etwa das, was Du da tust. Bzw. Du lädst die Sachen in einen Buffer und initialisiert damit den Vektor.
Um mehr ins definierte Verhalten zu rutschen, wäre ein std::array vielleicht interessant, wenn DimX, DimY und DimZ konstant sind. Das würde auch die Laufzeit verbessern.
Leverator hat geschrieben:
Sa Nov 06, 2021 5:13 pm
Ich hätte ehrlich gesagt erwartet, dass es eine Möglichkeit gibt, in C++ die einzulesende Struktur parametriert zu definieren und dann mit einem Befehl die Informationen in das RAM zu jagen (z.B. über DMA).
Die definierte Struktur würde sich dann wie eine Schablone auf die Daten legen.
Das geht so einfach nicht, weil die Vektoren Pointer enthalten und diese auch selbst verwalten. Du definierst ein Binärfile speicherst. Um das direkt in den Speicher zu jagen, müssen die Datenstrukturen auch ausschließlich und vollständig durch die File-Representation abgebildet werden und anschließend in der Größe unveränderlich sein. All das trifft auf Vektor nicht zu.
Auf Array schon eher...

Re: Effizientes Einlesen v. Binärdaten in Struktur(en)

Verfasst: Sa Nov 06, 2021 10:36 pm
von mfro
Bin nicht sicher, ob ich die Frage richtig verstehe, aber die sicherlich effizienteste Möglichkeit, ein Array mit Dateiinhalt zu füllen, ist der mmap()-Systemaufruf. Dabei wird der Dateiinhalt (ähnlich wie bei einem Swap-File) als Speicherbereich eingeblendet. Schreibzugriffe auf den Speicherbereich schreiben auf die Datei und Lesezugriffe lesen Daten von dort.

Wenn Du von std::vector ableitest und dort dessen Allokator mit mmap() Aufrufen überschreibst, hast Du im Prinzip, was Du wolltest.

Nicht ganz trivial und mit ein paar Fallstricken versehen, sollte aber grundsätzlich möglich sein,

Re: Effizientes Einlesen v. Binärdaten in Struktur(en)

Verfasst: So Nov 07, 2021 2:27 pm
von Xin
mfro hat geschrieben:
Sa Nov 06, 2021 10:36 pm
Wenn Du von std::vector ableitest und dort dessen Allokator mit mmap() Aufrufen überschreibst, hast Du im Prinzip, was Du wolltest.
Das könnte eventuell für einen Vektor funktionieren... das ursprüngliche Problem sind aber drei ineinander verschachtelte Vektoren.

Und für einen Vektor alleine wird das schon schwierig, weil der Allokator die Datei nicht kennen kann. Der Dateiname müsste als Template-Parameter übergeben werden und wäre damit auch nicht zur Laufzeit anpassbar.

Es stellt sich ein wenig die Frage, was der primäre Wunsch ist: Komfort, dann würde das auf ein ORM-System rauslaufen, oder Effizienz, was Datentyp abhängig wäre, also sehr speziell für den Problemfall programmiert werden müsste.

Re: Effizientes Einlesen v. Binärdaten in Struktur(en)

Verfasst: So Nov 07, 2021 4:39 pm
von Leverator
Okay...
Danke für Eure Antworten.
Es wird also darauf hinauslaufen, dass ich es so lasse, wie es ist.
Evtl. werde ich das Ganze eh noch vollkommen umstricken, um an anderer Stelle Performance herauszuholen.

Viele Grüße,
Lev

Re: Effizientes Einlesen v. Binärdaten in Struktur(en)

Verfasst: So Nov 07, 2021 5:32 pm
von mfro
Xin hat geschrieben:
So Nov 07, 2021 2:27 pm
Und für einen Vektor alleine wird das schon schwierig, weil der Allokator die Datei nicht kennen kann. Der Dateiname müsste als Template-Parameter übergeben werden und wäre damit auch nicht zur Laufzeit anpassbar.
Ich habe gerade das hier gefunden: https://github.com/johannesthoma/mmap_allocator - da hat sich schon jemand die Mühe gemacht und die Idee (wie ich meine - ziemlich gut) umgesetzt.

Der Dateiname ist kein Problem.

Die Fleissaufgabe wäre jetzt noch, Vektoren "schachteln" zu können. Nicht unmöglich, aber es stellt sich die Frage, ob der Aufwand gerechtfertigt ist.

Re: Effizientes Einlesen v. Binärdaten in Struktur(en)

Verfasst: So Nov 07, 2021 7:31 pm
von Xin
mfro hat geschrieben:
So Nov 07, 2021 5:32 pm
Die Fleissaufgabe wäre jetzt noch, Vektoren "schachteln" zu können. Nicht unmöglich, aber es stellt sich die Frage, ob der Aufwand gerechtfertigt ist.
Ich denke, dass genau das eben nicht die Fleißaufgabe ist, sondern die eigentliche Herausforderung. ^^