2 Stimmen

Ist es möglich, kleinere speicherabgebildete Ansichten für eine 2 GB+ große Datei zu erstellen?

Ich habe eine C++-Klasse für Windows und Linux geschrieben, die eine speicherabbildende Ansicht für eine Datei beliebiger Größe n erstellt. Der Code für den Klassenkonstruktor kann hier eingesehen werden . Ich teste den Code derzeit unter Windows 32 Bit XP.

Ich habe festgestellt, dass der Konstruktor für die Dateigrößen 0 < n <= 1,7 GB einen gültigen Zeiger auf eine speicherabgebildete Ansicht zurückgibt. Bei einer Dateigröße >= 2 GB gibt MapViewOfFile jedoch einen NULL-Wert und den Fehlercode 8 zurück: "Für die Verarbeitung dieses Befehls ist nicht genügend Speicherplatz verfügbar". Offensichtlich kann Windows keinen verfügbaren Adressraum der Größe 2 GB im Prozess finden.

Daher muss ich möglicherweise den Klassenkonstruktor ändern, um eine Reihe kleinerer speicherabgebildeter Ansichten zu erstellen, die insgesamt >= 2 GB Bytes && < 2 ^ 32 - 1 Bytes umfassen. Die andere Anforderung besteht darin, eine Zuordnung zwischen jeder der kleineren speicherabgebildeten Ansichten und einer Adresse mit zufälligem Zugriff im Adressraum des Prozesses zu erstellen.

Zuvor habe ich den folgenden Code für den wahlfreien Zugriff verwendet:

char* KeyArray;

try {
    mmapFile = new cMemoryMappedFile(n);
}
catch (cException e)
{
    throw;
}

KeyArray = (char *)(mmapFile->GetPointer());
KeyArray[i] = ...

Wie sollte ich die Klasse ändern, um diese Anforderungen zu erfüllen?

0 Stimmen

Hier ist die Pastebin-Url. <iframe src=" pastebin.com/embed_iframe.php?i=2GX0XHsm " style="border:none;width:100%"></iframe>

0 Stimmen

3voto

vissi Punkte 2356

Das, was Sie wollen, können Sie mit Repaging erreichen. Sehen Sie sich an, wie das in boost.iostreams gemacht wird aquí .

0 Stimmen

Ich danke Ihnen für Ihre Antwort. Wir können boost erst einsetzen, wenn wir die Genehmigung für die neuesten Solaris Unix-, IBM AIX- und HPUX-Lizenzen erhalten haben. Ich bitte um Entschuldigung, dass ich das nicht erwähnt habe. Könnten wir uns den boost-Code ansehen und ihn für Windows, Linux und Unix anpassen? Ich danke Ihnen.

0 Stimmen

Ich habe ein Repaging-Beispiel für boost.iostreams serial access gefunden. Ich danke Ihnen für Ihre Antwort.

3voto

Nur Sie haben 2 GB (oder 3 GB, mit einigen Optimierungen) Speicherplatz für Benutzerprozesse in einem 32-Bit-Betriebssystem. Punkt. Das ist eine harte Einschränkung, die auch durch die Erstellung vieler kleinerer Mappings nicht umgangen werden kann. Sie müssen Ihre Mappings verschieben, um auf die verschiedenen Teile der Datei zugreifen zu können. Aber es wird immer noch schneller sein als Suchen, Lesen und Schreiben.

0 Stimmen

@Ignacio Vazquez-Abrams: Nicht das Mapping muss verschoben werden, sondern die Ansicht. Oder liege ich da falsch? ... oh, tut mir leid, ich habe gerade bemerkt, dass es zwischen Linux und Windows geteilt wird, ich bin mir nicht sicher, inwieweit das auch für Linux gilt.

0 Stimmen

Ja, unter Win32 wäre es die Ansicht, die verschoben werden muss.

0 Stimmen

@Ignacio Vazquez-Abrams: hehe, gleicher Gedanke. Hatte meinen Kommentar bearbeitet und deiner erschien ;)

2voto

wilx Punkte 17189

Das wird nicht funktionieren. Sie können einfach nicht alle 4 GiB des Adressraums unter 32-Bit-Windows verwenden. Gestalten Sie den Zugriff auf das Array neu, um nur kleine Teile der großen Datei abzubilden.

0 Stimmen

Wilx, ich möchte nur Adressraum < 2 ^ 32 - 1 Bytes verwenden. Ist das möglich? Ich danke Ihnen für Ihre Antwort.

0 Stimmen

@Frank: Ja, unter Windows wäre das der Fall. Das Mapping kann die gesamte Datei umfassen, während die Ansicht theoretisch bis zu 2 GiB groß sein kann. Da aber einige Entitäten bereits in Ihrem Prozessspeicher liegen, bezweifle ich, dass Sie wirklich bis zu 2 GiB bekommen.

0 Stimmen

@STATUS_ACCESS_DENIED, Könnten Sie uns mitteilen, wie wir die Ansicht innerhalb der Zuordnung verschieben können? Vielen Dank für Ihre Antwort,

2voto

royce3 Punkte 878

Ich kann Ihren Pastebin-Link nicht sehen, aber ich kann eine einfache Lösung mit einer C++-Klassendeklaration vorschlagen. Ich denke, die Implementierung sollte aus den Kommentaren ersichtlich sein:

class ShiftingMemMap
{
public:
    // constructs a dynamically shifting memory map of a file...
    ShiftingMemMap ( const char* fileName, size_t view_size = 4096 );

    // retrieve/set a byte at the given file offset. If the offset is not currently in-view,
    // shift the view to encompass the offset. The reference should not be stored for later
    // access because the view may need to shift again...
    byte& operator [] ( unsigned int_64_t offset );

private:
    int_64_t current_offset;
    size_t current_size;
};

Trotzdem könnte man eine Klasse schreiben, die mehrere Ansichten einer Datei zurückgibt, um einen Verweis für später zu speichern und auch verschiedene Teile der Datei gleichzeitig zu bearbeiten, ohne die Ansicht immer wieder hin und her schieben zu müssen.

class MemMap
{
public:
    MemMap ( const char* filename );

    shared_ptr<MemMapView> View ( unsigned int_64_t offset, size_t size = 4096 );
};

class MemMapView
{
public:
    char& operator[] ( size_t offset );
};

0 Stimmen

Royce3, mein Vorgesetzter sagte mir, ich solle dieses Problem ohne Boost lösen, weil unser potenzielles Produkt auf Windows, Linux, Oracle Solaris Unix, IBM AIX UNIX und HPUX laufen muss. Unter Windows und Linux verwenden wir die neuesten Versionen. Auf Oracle Solaris UNIX und HPUX sind die Kosten für die neueste UNIX-Distribution jedoch unerschwinglich, so dass wir BOOST auf Oracle Solaris UNIX und HPUX nicht verwenden können. Letzte Woche konnten wir dieses Problem jedoch mit STL und unserer eigenen doppelt verknüpften Klasse lösen, die über einen benutzerdefinierten Speicherzuweiser verfügt. Vielen Dank für Ihre Antwort, Frank Chang

0 Stimmen

Royce3, ich habe gerade Ihre Antwort akzeptiert, weil ich sie für ausgezeichnet halte. Ich danke dir.

0voto

Frank Punkte 1376

Ja, es ist möglich, eine C++-Klasse für Windows, Solaris Unix und Linux zu schreiben, die eine speicherzugeordnete Ansicht für eine Datei beliebiger Größe n erstellt. Wir haben gerade zwei Versionen der Klasse fertiggestellt, eine mit STL und die andere, die mein Chef geschrieben hat und die keine STL verwendet. Beide Versionen sind besser als die Verwendung des Heaps, wenn die Größe der Speicherzuweisung 1 Gigabyte oder mehr unter 32-Bit-Windows, Linux und Solaris Unix beträgt. Beide Versionen sind auch mit 64-Bit-Windows, Linux und Solaris Unix kompatibel. Wenn Sie mehr Details darüber erfahren möchten, senden Sie mir bitte eine E-Mail an frankchang91@gmail.com. Massachusetts, USA. Diese 2 Versionen wurden unabhängig voneinander entwickelt und könnten Teil einer US-Patentanmeldung zur Datenfusion werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X