Disclaimer: Ich entschuldige mich für die Ausführlichkeit dieser Frage (ich denke, es ist ein interessantes Problem, obwohl!), Aber ich kann nicht herausfinden, wie um es prägnanter zu formulieren.Zugriff auf> 2,3,4GB Dateien in 32bit Prozess auf 64bit (oder 32bit) Windows
Ich habe Stunden der Forschung getan, wie auf den scheinbar von Möglichkeiten, unzählige, in denen das Problem des Zugriff auf Multi-GB-Dateien in einem 32-Bit-Prozess auf 64-Bit-Windows 7 zu lösen, von /LARGEADDRESSAWARE
zu VirtualAllocEx
AWE reicht. Ich bin ein wenig in der Lage, ein System mit mehreren Speicherabbildern in Windows zu schreiben (CreateFileMapping, MapViewOfFile usw.), kann jedoch dem Gefühl, dass es eine elegantere Lösung für dieses Problem gibt, nicht ganz entkommen. Außerdem bin ich mir der Boost-Interprozessor- und Iostream-Templates durchaus bewusst, obwohl sie ziemlich leichtgewichtig zu sein scheinen und einen ähnlichen Aufwand erfordern, um ein System zu schreiben, das nur Windows-API-Aufrufe verwendet (ganz zu schweigen von der Tatsache, dass ich bereits einen Speicher habe). gemappte Architektur, die unter Verwendung von Windows-API-Aufrufen teilweise implementiert wurde).
Ich versuche, große Datensätze zu verarbeiten. Das Programm ist auf vorkompilierte 32-Bit-Bibliotheken angewiesen, weshalb das Programm derzeit auch in einem 32-Bit-Prozess läuft, obwohl das System 64-Bit-fähig ist, mit einem 64-Bit-Betriebssystem. Ich weiß, dass es Wege gibt, auf denen ich Wrapper-Bibliotheken hinzufügen könnte, aber da es Teil einer größeren Codebasis ist, wäre es in der Tat ein bisschen ein Unternehmen. Ich setze die binären Header auf /LARGEADDRESSAWARE
(auf Kosten der Verringerung meiner Kernel-Speicherplatz?), So dass ich bis zu etwa 2-3 GB adressierbaren Speicher pro Prozess, geben oder nehmen (abhängig von Heap-Fragmentierung, etc.) .
Hier ist das Problem: Die Datensätze sind 4 + GB, und DSP-Algorithmen laufen auf ihnen, die im Wesentlichen wahlfreien Zugriff über die Datei erfordern. Ein Zeiger auf das aus der Datei erzeugte Objekt wird in C# behandelt, die Datei selbst wird jedoch in C++ (mit P/Invoked) in den Speicher geladen (mit diesem partiellen Speicherabbildungssystem). Daher glaube ich, dass die Lösung leider nicht so einfach ist, einfach die Fensterung anzupassen, um auf den Teil der Datei zuzugreifen, auf den ich zugreifen muss, da ich im Wesentlichen die gesamte Datei in einen einzigen Zeiger abstrahieren möchte, von dem ich Methoden aufrufen kann Zugriff auf Daten fast überall in der Datei. Die Speicherarchitekturen basieren anscheinend auf der Aufteilung des singulären Prozesses in mehrere Prozesse. So würde ich zum Beispiel auf eine 6-GB-Datei mit 3x Prozessen zugreifen, von denen jeder ein 2-GB-Fenster für die Datei enthält. Ich müsste dann eine signifikante Menge an Logik hinzufügen, um Daten aus diesen verschiedenen Fenstern/Prozessen zu ziehen und neu zu kombinieren. VirtualAllocEx
bietet anscheinend eine Methode, den virtuellen Adressraum zu vergrößern, aber ich bin immer noch nicht ganz sicher, ob dies der beste Weg ist, um darüber zu gehen.
Aber sagen wir, ich möchte, dass dieses Programm genauso "einfach" funktioniert wie ein singulärer 64bit Prozess auf einem 64bit System. Nehmen wir an, dass es mir egal ist, wenn ich mich prügele, ich möchte nur eine große Datei auf dem System manipulieren können, auch wenn nur 500 MB in den physischen Arbeitsspeicher geladen wurden. Gibt es eine Möglichkeit, diese Funktionalität zu erhalten, ohne ein etwas lächerliches, manuelles Speichersystem von Hand schreiben zu müssen? Oder gibt es einen besseren Weg als das, was ich durch SO und das Internet gefunden habe?
Dies ergibt sich für eine sekundäre Frage: Gibt es eine Möglichkeit zu begrenzen, wie viel physisches RAM von diesem Prozess verwendet werden würde? Was wäre zum Beispiel, wenn ich den Prozess auf nur 500 MB beschränken möchte, die gleichzeitig in physischen RAM geladen werden (während die Multi-GB-Datei auf der Festplatte gespeichert bleibt)?
Es tut mir leid für die lange Frage, aber ich habe das Gefühl, es ist eine anständige Zusammenfassung von dem, was viele Fragen (mit nur teilweise Antworten), die ich auf SO und das Netz insgesamt gefunden habe. Ich hoffe, dass dies ein Bereich sein kann, in dem eine definitive Antwort (oder zumindest einige Vor-/Nachteile) ausgearbeitet werden kann und wir alle etwas wertvolles lernen können!
tl; dr, aber wenn Sie eine externe Bibliothek verwenden möchten: Qt kann "große Dateien" plattformübergreifend verarbeiten, jedoch nicht speicherabgebildet (auf 32-Bit-Plattformen). Aber es verwendet einen internen IO-Cache, der * eine vergleichbare Leistung * erreichen kann? – leemes
Danke für den Kommentar, leemes (obwohl tl; dr ist etwas unhöflich zu sagen> _> ;;)! Ich habe mit einem internen IO-Cache nachgedacht, aber das scheint eine ziemlich große Menge an Komplexität einzuführen, was ich zu vermeiden versuche. Außerdem möchte ich vermeiden, zusätzliche Bibliotheken wie Qt zum Mix hinzuzufügen (Boost ist jedoch bereits integriert) –
Begrenzung des Arbeitsspeichers, Sie könnten ein Windows-Job-Objekt verwenden und den Arbeitssatz begrenzen, der physischen RAM einschränkt. Leider denke ich, dass dies nur das Austauschen maximieren wird, also ist es nicht das, was Sie möglicherweise wollen. Ich nehme auch an, dass Sie über Memory-Mapped-Dateien Bescheid wissen und diese nicht Ihren Bedürfnissen entsprechen. –