Frage

POSIX-Umgebungen bieten auf mindestens zwei Arten von Dateien zugreifen. Es gibt die Standard-Systemaufrufe open(), read(), write() sowie Freunde, aber es gibt auch die Möglichkeit, mmap() unter Verwendung der Datei in den virtuellen Speicher abzubilden.

Wann ist es vorzuziehen, einen über den anderen zu bedienen? Was sind ihre individuellen Vorteilen, die Verdienst einschließlich zwei Schnittstellen?

War es hilfreich?

Lösung

mmap ist groß, wenn Sie mehrere Prozesse Zugriff auf Daten in einer Nur-Lese-Mode aus der gleichen Datei haben, die in der Art von Server-Systemen üblich ist ich schreibe. mmap können alle diese Prozesse die gleichen physikalischen Speicherseiten teilen, viel Speicher zu speichern.

Mmap ermöglicht auch die Betriebssystem-Paging-Operationen zu optimieren. Betrachten wir zum Beispiel zwei Programme; Programm A, das in einer 1 MB-Datei in einen Puffer mit malloc Schaffung liest, und das Programm B, die die 1MB Datei in den Speicher mmaps. Wenn das Betriebssystem Teil A Speicher aus tauschen hat, muss er den Inhalt des Puffers schreiben zu tauschen, bevor es die Speicher wiederverwenden kann. In B Fall irgendwelche unmodifizierten mmap'd Seiten können sofort wieder verwendet werden, da das Betriebssystem weiß, wie sie aus der bestehenden Datei wiederherzustellen, sie aus mmap'd wurden. (Das Betriebssystem kann durch zunächst Markierung beschreibbaren mmap'd Seiten, welche Seiten sind unmodifizierte erkennen als nur lesen und Fehler seg kontrollieren, ähnlich zu schreiben Strategie kopieren).

mmap ist auch nützlich für die Inter-Prozess-Kommunikation. Sie können eine Datei als Lese mmap / in den Prozessen schreiben, die Synchronisations-Primitiven in der mmap'd Region kommunizieren müssen und dann verwenden (das ist, was die MAP_HASSEMAPHORE Flagge ist für).

Ein Ort Mmap kann umständlich sein, wenn man mit sehr großen Dateien auf einem 32-Bit-Maschine arbeiten müssen. Dies liegt daran, mmap hat einen zusammenhängenden Block von Adressen zu finden in Adressraum Ihres Prozesses ist, der groß genug ist, um die gesamte Bandbreite der Datei paßt abgebildet werden. Dies kann zu einem Problem werden, wenn Ihr Adressraum fragmentiert wird, wo man 2 GB Adressraum frei haben könnte, aber kein einzelner Bereich davon kann eine 1 GB Dateizuordnung passen. In diesem Fall können Sie die Datei in kleinere Stücke kartieren, als Sie es fit machen möchten.

Eine weitere potenzielle Ungeschicklichkeit mit mmap als Ersatz für Lese- / Schreib ist, dass Sie Ihre Zuordnung auf Offsets der Seitengröße beginnen. Wenn Sie nur einige Daten bei Offset X erhalten möchten, müssen Sie, dass es so kompatibel Offset fixup mit mmap.

Und schließlich lesen / schreiben sind der einzige Weg, können Arbeit mit einigen Arten von Dateien. mmap kann nicht auf Dinge wie Rohre und ttys verwendet werden.

Andere Tipps

Ein Bereich, wo ich mmap () gefunden kein Vorteil zu sein, als kleine Dateien zu lesen (unter 16 KB). Der Overhead des Seitenfehlers die gesamte Datei zu lesen war sehr hoch im Vergleich mit nur einen einzigen Lese () Systemaufruf zu tun. Das ist, da der Kernel manchmal eine Lese ganz in Ihrer Zeitscheibe satisify können, Ihren Code bedeutet weg schaltet nicht. Mit einem Seitenfehler, schien es wahrscheinlicher, dass ein anderes Programm würde geplant werden, so dass die Dateioperation eine höhere Latenz.

mmap hat den Vorteil, wenn Sie auf große Dateien mit wahlfreiem Zugriff haben. Ein weiterer Vorteil ist, dass man es mit Speicheroperationen zugreifen (memcpy, Zeigerarithmetik), ohne mit dem Puffer stört. Normale E / A kann manchmal recht schwierig sein, wenn Puffer verwenden, wenn Sie Strukturen größer als Ihr Puffer haben. Der Code zu handhaben, dass oft schwierig ist, richtig zu machen, ist Mmap der Regel einfacher. Das heißt, es gibt bestimmte Fallen, wenn sie mit mmap arbeiten. Da die Menschen bereits erwähnt haben, ist mmap ziemlich teuer einzurichten, so lohnt es sich, nur für eine bestimmte Größe mit (von Maschine zu Maschine variiert).

Für reine sequentielle Zugriffe auf die Datei, es ist auch nicht immer die bessere Lösung, wenn ein entsprechender Aufruf madvise das Problem mildern kann.

Sie haben mit Ausrichtung Einschränkungen Ihrer Architektur (SPARC, itanium), mit Lese / Schreib-IO die Puffer sind oft richtig ausgerichtet ist und nicht Falle vorsichtig sein, wenn eine gegossene Zeiger Dereferenzierung.

Sie müssen auch darauf achten, dass Sie nicht außerhalb der Karte zugreifen. Es kann leicht passieren, wenn Sie String-Funktionen auf Ihrer Karte verwenden, und die Datei nicht über eine \ 0 am Ende enthalten. Es wird fast die ganze Zeit arbeiten, wenn die Dateigröße nicht ein Vielfaches der Seitengröße ist als die letzte Seite mit 0 gefüllt ist (das abgebildete Bereich ist immer in der Größe eines Vielfachen von Ihrer Seite Größe).

Neben anderen netten Antworten, ein Zitat von Linux Systemprogrammierung geschrieben von Google-Experten Robert Love:

  

Vorteile von mmap( )

     

Dateien über mmap( ) Manipulieren hat eine Handvoll von Vorteilen gegenüber der   Standard read( ) und write( ) Systemaufrufe. Unter ihnen sind:

     
      
  • Lesen von und Schreiben auf eine Memory-Mapped-Datei die vermeidet   Fremdkopie, die auftritt, wenn das read( ) oder write( ) System   Anrufe, wo die Daten zu und von einem User-Space-Puffer kopiert werden müssen.

  •   
  • Neben potenziellen Seitenfehlern beim Lesen und Schreiben auf eine Memory-Mapped-Datei entsteht keinen Systemaufruf oder Kontextwechsel   Overhead. Es ist so einfach, wie Zugriff auf den Speicher.

  •   
  • Wenn mehr Prozesse auf das gleiche Objekt in den Speicher abzubilden, werden die Daten unter allen Prozessen gemeinsam genutzt. Read-only und gemeinsame beschreibbare   Zuordnungen sind in ihrer Gesamtheit geteilt; Private beschreibbaren Zuordnungen haben   ihr noch nicht COW (copy-on-write) Seiten geteilt.

  •   
  • Ich suche um das Mapping beinhaltet trivial Zeiger Manipulationen. Es besteht keine Notwendigkeit für den lseek( ) Systemaufruf.

  •   
     

Aus diesen Gründen mmap( ) ist eine kluge Wahl für viele Anwendungen.

     

Nachteile von mmap( )

     

Es gibt ein paar Punkte im Auge zu behalten, wenn mmap( ) mit:

     
      
  • Speicherzuordnungen sind immer eine ganze Anzahl von Seiten in der Größe. Somit ist die Differenz zwischen der Größe der Trägerdatei und einem   ganzzahlige Anzahl von Seiten wird als Schlupfspeicher „verschwendet“. Bei kleinen Dateien ein   bedeutender Prozentsatz des Mappings verschwendet werden. Zum Beispiel mit   4-KB-Seiten, ein 7-Byte-Mapping Abfälle 4089 Bytes.

  •   
  • Die Speicherzuordnungen muss den Prozess Adressraum passen. Mit einem 32-Bit-Adressraum, eine sehr große Anzahl von unterschiedlich großen Mappings   kann zu einer Fragmentierung des Adressraums zur Folge haben, macht es schwer, zu   findet große freie angrenzende Regionen. Dieses Problem ist natürlich viel   weniger offensichtlich mit einem Adressraum 64-Bit.

  •   
  • Es Overhead ist bei der Erstellung und die Speicherzuordnungen und zugehörige Datenstrukturen im Kernel aufrechterhalten wird. Dieser Aufwand ist   im allgemeinen vermieden erwähnt durch die Eliminierung der Doppelkopie in   Im vorhergehenden Abschnitt, insbesondere für größere und häufig zugegriffen   Dateien.

  •   
     

Aus diesen Gründen sind die Vorteile des mmap( ) am stärksten realisiert   wenn die abgebildete Datei groß ist (und damit jeder verschwendete Raum ist ein kleines   Prozentsatz des Gesamt mapping), oder wenn die Gesamtgröße des abgebildeten   Datei ist teilbar durch die Seitengröße (und somit gibt es keine verschwendete   Raum).

Memory Mapping hat ein Potential für einen großen Geschwindigkeitsvorteil im Vergleich zu herkömmlichen IO. Es ermöglicht das Betriebssystem die Daten aus der Quelldatei zu lesen, wie die Seiten in den Speicher abgebildeten Datei berührt werden. Dies funktioniert durch Verwerfungen Seiten zu schaffen, die das Betriebssystem erkennt und dann das Betriebssystem lädt die entsprechenden Daten aus der Datei automatisch.

Dies funktioniert auf die gleiche Weise wie der Paging-Mechanismus und in die Regel für hohe Geschwindigkeit optimiert ist, I / O von Daten auf Systemseite Grenzen zu lesen und Größen (in der Regel 4K) -. Größe für die meisten Dateisystem-Caches optimiert werden

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top