sucht nach Windows-RAM-basierten Shared Memory-Lösung in C ++

8

Ich stehe vor einer Situation, in der ich mehrere hundert Megabytes Speicher von einem Prozess zum anderen weitergeben muss. Im Moment mache ich es über Dateien und es ist zu langsam. Ich denke, um es schneller zu machen, sollten diese Dateien direkt in den RAM geschrieben werden und von einem anderen Prozess aus zugänglich sein. Keine ausgefallene Synchronisation erforderlich. Ein Prozess würde gemeinsam genutzte Speicherobjekte erstellen und diese mit Daten füllen. Der andere Prozess würde sie lesen und entfernen. Ich habe jedoch eine kurze Recherche durchgeführt und es scheint, als ob Sie keinen Speicher im RAM in Windows freigeben können - der gemeinsam genutzte Speicher wird entweder von einer Datei oder einer Auslagerungsdatei unterstützt. Die Dokumentation von boost :: interprocess bestätigt dies. Wo ist die Geschwindigkeit dann, wenn die Shared-Memory-Implementierung noch Datenträger verwendet? Gibt es eine C ++ - Bibliothek, die RAM-basierten Shared Memory verwendet?

EDIT: Ich habe noch etwas gelesen: 1. von boost :: interprocess docs: "Da das Betriebssystem den Dateiinhalt mit dem Speicherinhalt synchronisieren muss, sind Speicherkarten nicht so schnell wie Shared Memory." 2. von Ссылка : "Eine speicherabgebildete Datei kann auch von mehr als einer Anwendung gleichzeitig zugeordnet werden. Dies ist der einzige Mechanismus für zwei oder mehr Prozesse, Daten direkt in Windows NT zu teilen."

    
andriej 02.06.2011, 00:39
quelle

4 Antworten

13

Ich denke, dass hier ein fundamentales Missverständnis besteht: Sie denken, dass wenn Sie eine Dateizuordnung erstellen, die von der Auslagerungsdatei unterstützt wird, so langsam ist, wie das Schreiben von Daten auf der Festplatte.

Dies ist definitiv nicht der Fall: Die Bedeutung von "unterstützt durch die Auslagerungsdatei" in der Dokumentation bedeutet, dass der gemeinsame Speicher im Allgemeinen im Speicher liegt, aber er hat einen reservierten Platz in der Auslagerungsdatei, um solche Daten zu schreiben, falls vorhanden nicht genug freier physischer Speicher und der virtuelle Speichermanager muss Speicherseiten austauschen.

Dies ist nicht wirklich klar aus der Dokumentation, aber die Dateizuordnung Seite auf MSDN bestätigt:

  

[...] Es wird von der Datei auf der Festplatte gesichert. Dies bedeutet, dass beim Auslagern von Seiten des Dateizuordnungsobjekts alle Änderungen am Dateizuordnungsobjekt in die Datei geschrieben werden. Wenn die Seiten des Dateizuordnungsobjekts wieder eingetauscht werden, werden sie aus der Datei wiederhergestellt.

Beachten Sie, dass dies für den gemeinsam genutzten Speicher gilt, der von der Auslagerungsdatei unterstützt wird, sowie für den von regulären Dateien unterstützten Speicher (der VMM garantiert, dass die verschiedenen Ansichten kohärent bleiben).

Übrigens funktioniert so "normaler" (= virtueller) Speicher in Benutzerprozessen: Jedes Bit des zugewiesenen Speichers kann in die Auslagerungsdatei ausgelagert werden, wenn es nicht gerade verwendet wird und das System physischen Speicher für andere Dinge verwenden muss (zB Erstellen von Speicherseiten, die gerade verwendet werden, für Ihre / eine andere Anwendung).

    
Matteo Italia 02.06.2011, 13:40
quelle
6

Es ist nichts falsch daran, von einer Datei zu werden - unter dem Druck des Speichers müssen die Daten irgendwo hingehen, und Ihre Auswahlmöglichkeiten sind:

  • Behandle die Erinnerung als heilige Daten, die nicht paginiert oder gelöscht werden können

    Wahrscheinlich werden nur viel schlechtere Speicherdruckprobleme erzeugt, aber eine gute Wahl für einige eingebettete Systeme, bei denen die gesamte Laufzeitumgebung des Systems sehr gut kontrolliert werden kann.

  • lösche den Speicher

    Offensichtlich nicht für alle Daten geeignet. Zwischengespeicherte Inhalte? Könnte sein. Original-Fotos? Wahrscheinlich nicht.

  • page den Speicher auf die Festplatte

    Gute generische Wahl!

Wird bei Verwendung eines Shared-Memory-Tools der Arbeitsspeicherdruck angezeigt? Fügen Sie mehr RAM hinzu oder erfahren Sie, wie Sie Ihre Systeme verkleinern können. :)

    
sarnold 02.06.2011 01:10
quelle
3

Soweit ich weiß, haben Sie im Wesentlichen 2 Optionen hier.

1) Sie erstellen eine DLL und verwenden das Pragma data_seg und laden die DLL in Ihren beiden Prozessen. Dies hat RIESIGE Nachteile, die hier im Detail erklärt werden: Ссылка

Die wichtigsten Nachteile sind: Der Speicherplatz muss statisch initialisiert werden und wird im Datensegment der kompilierten DLL gespeichert. Wenn Sie also Hunderte von MBs mit dieser Methode teilen möchten, wird Ihre DLL Hunderte von sein MBs groß.

2) Es ist nichts dagegen, normale Memory-Mapped-Dateien zu verwenden, da sie sowieso zwischengespeichert werden. Sie können die System-Auslagerungsdatei sogar verwenden, um die Daten wie in diesem Artikel beschrieben zu speichern: Ссылка

Ich habe dieses Beispiel [1] der Interprozesskommunikation tatsächlich getestet Mit einer 1 GiB Memory-Mapped-Datei und kann bestätigen, dass nichts auf die Festplatte geschrieben wurde, auch nachdem das gesamte GiB mit Daten gefüllt wurde.

[1] Ссылка

    
PeterT 02.06.2011 01:13
quelle
1

Ich würde immer noch Speicher-Mapped-Dateien anstelle des Ansatzes vorschlagen, den ich erwähnen werde.

Wenn Sie wirklich aus einem anderen Prozessspeicher lesen möchten , verwenden Sie Win32 API ReadProcessMemory () .

Wenn Sie paranoid sind, Daten im RAM zu halten, gibt es Unix mlock () Entsprechungen in MS Windows VirtualLock ()

    
hackworks 02.06.2011 13:27
quelle

Tags und Links