GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Warum ist mmap() schneller als sequentielles IO?

Ich habe gehört (irgendwo im Internet gelesen), dass mmap() schneller ist als sequentielles IO. Ist das richtig? Wenn ja, warum ist es dann schneller?

Es kann sein - es gibt Vor- und Nachteile, die unten aufgeführt sind. Wenn Sie wirklich Grund zur Sorge haben, vergleichen Sie immer beides .

Abgesehen von der tatsächlichen E/A-Effizienz gibt es Auswirkungen auf die Art und Weise, wie der Anwendungscode verfolgt, wann er die E/A ausführen muss, und wie Daten verarbeitet/generiert werden, was sich manchmal ziemlich dramatisch auf die Leistung auswirken kann.

  1. mmap() liest nicht sequentiell.2) mmap() muss genauso wie read() von der Platte selbst lesen3) Der gemappte Bereich ist nicht sequentiell - also kein DMA (?).

Also sollte mmap() eigentlich langsamer sein als read() aus einer Datei? Welche meiner obigen Annahmen sind falsch?

  1. ist falsch... mmap() Weist einen Bereich des virtuellen Adressraums zu, der dem Dateiinhalt entspricht ... Immer wenn auf eine Seite in diesem Adressraum zugegriffen wird, wird der physische RAM gefunden, um die virtuellen Adressen zu unterstützen, und der entsprechende Festplatteninhalt wird in diesen RAM verschoben. Die Reihenfolge, in der Lesevorgänge von der Festplatte durchgeführt werden, stimmt also mit der Zugriffsreihenfolge überein. Es ist ein "fauler" I/O-Mechanismus. Wenn Sie zum Beispiel in eine riesige Hash-Tabelle indizieren mussten, die von der Festplatte gelesen werden sollte, dann mmap Das Speichern der Datei und der Beginn des Zugriffs bedeutet, dass die Festplatten-E/A nicht sequenziell ausgeführt wird, und kann daher zu einer längeren verstrichenen Zeit führen, bis die gesamte Datei in den Speicher eingelesen ist, aber während dies geschieht, sind Suchvorgänge erfolgreich und abhängige Arbeiten können durchgeführt werden, und wenn Teile der Datei nie wirklich benötigt werden, werden sie nicht gelesen (erlauben Sie die Granularität von Festplatten- und Speicherseiten, und selbst wenn Sie die Speicherzuordnung verwenden, erlauben Ihnen viele Betriebssysteme, einige Tipps zur Leistungssteigerung / Speichereffizienz über Ihre geplanten Zugriffsmuster, damit sie proaktiv vorauslesen oder Speicher aggressiver freigeben können, da sie wissen, dass Sie wahrscheinlich nicht darauf zurückkommen werden).

  2. absolut wahr

  3. "Der abgebildete Bereich ist nicht sequenziell" ist vage. Speicherabgebildete Bereiche sind im virtuellen Adressraum "zusammenhängend" (sequentiell). Wir haben oben besprochen, dass Festplatten-I/O sequenziell sind. Oder fällt Ihnen etwas anderes ein? Wie auch immer, während Seiten fehlerhaft sind, können sie tatsächlich mit DMA übertragen werden.

Darüber hinaus gibt es noch andere Gründe, warum die Speicherzuordnung die übliche E/A übertreffen kann:

  • Es wird weniger kopiert:
    • Häufig leiten Routinen auf Betriebssystem- und Bibliotheksebene Daten durch einen oder mehrere Puffer, bevor sie einen von der Anwendung angegebenen Puffer erreichen. Die Anwendung weist dann dynamisch Speicher zu und kopiert dann aus dem E/A-Puffer in diesen Speicher, sodass die Daten nach der Datei verwendbar sind Lesevorgang abgeschlossen
    • Memory-Mapping erlaubt (erzwingt aber nicht) direkte Verwendung (Sie können einfach einen Zeiger und möglicherweise eine Länge aufzeichnen)
      • Ein weiterer Zugriff auf Daten vor Ort birgt erhöhte Cache-Fehler und/oder späteres Auslagern:Die Datei/Speicherkarte könnte ausführlicher sein als Datenstrukturen, in die sie geparst werden könnte, sodass Zugriffsmuster auf darin enthaltene Daten mehr Verzögerungen aufweisen könnten mehr Speicherseiten einzufügen
  • Speicherzuordnung kann den Parsing-Job der Anwendung vereinfachen, indem die Anwendung den gesamten Dateiinhalt als zugänglich behandelt, anstatt sich Gedanken darüber zu machen, wann ein weiterer Puffer voll gelesen werden soll
  • Die Anwendung verlässt sich mehr auf die Weisheit des Betriebssystems in Bezug auf die Anzahl der Seiten, die sich zu einem bestimmten Zeitpunkt im physischen RAM befinden, und teilt sich effektiv einen Festplatten-Cache mit direktem Zugriff mit der Anwendung
  • so kommentiert der Gratulant weiter unten:"Mit der Speicherzuordnung verwenden Sie normalerweise weniger Systemaufrufe"
  • Wenn mehrere Prozesse auf dieselbe Datei zugreifen, sollten sie in der Lage sein, die physischen Backing Pages gemeinsam zu nutzen

Das sind auch Gründe, warum mmap kann langsamer sein - lesen Sie hier den Beitrag von Linus Torvald, in dem von mmap die Rede ist :

... Seitentischspiele zusammen mit dem Fehler (und sogar nur TLB-Verfehlung) Overhead ist leicht mehr als die Kosten für das Kopieren einer Seite in einer Nicestreaming-Manier ...

Und aus einem anderen seiner Beiträge:

  • ziemlich spürbare Einrichtungs- und Abbaukosten. Und ich meine auffällig . Es geht beispielsweise darum, den Seitentabellen zu folgen, um alles sauber aufzulösen. Es ist die Buchhaltung, um eine Liste aller Zuordnungen zu führen. Es ist der TLB-Flush, der nach dem Aufheben der Zuordnung benötigt wird.
  • Seitenfehler sind teuer. So wird das Mapping gefüllt und es ist ziemlich langsam.

Linux hat "Hugepages" (also einen TLB-Eintrag pro 2 MB statt pro 4 KB) und sogar transparente Huge Pages, wo das Betriebssystem versucht, sie zu verwenden, selbst wenn der Anwendungscode nicht explizit dafür geschrieben wurde.

FWIW, das letzte Mal, als dies bei mir bei der Arbeit auftrat, war die speicherabgebildete Eingabe 80 % schneller als fread et al. zum Einlesen binärer Datenbankeinträge in eine proprietäre Datenbank unter 64-Bit-Linux mit ~170 GB Dateien.


  1. mmap() kann zwischen Prozessen geteilt werden.
  2. DMA wird wann immer möglich verwendet. DMA erfordert keinen zusammenhängenden Speicher – viele High-End-Karten unterstützen Scatter-Gather-DMA.
  3. Der Speicherbereich kann nach Möglichkeit mit dem Kernel-Block-Cache geteilt werden. Es wird also vom Vermieter kopiert.
  4. Speicher für mmap vom Kernel zugewiesen wird, ist es immer ausgerichtet.

Linux
  1. Warum ist die Windows10-VM auf OpenStack langsam?

  2. Warum ist Printf besser als Echo?

  3. Linux – Warum zeigt Linux sowohl mehr als auch weniger Speicher an, als ich physisch installiert habe?

  4. Warum Install statt Cp und Mkdir verwenden?

  5. Warum ist Wget viel schneller als das Herunterladen über Chrome?

Erfahren Sie, warum der Befehl „weniger“ schneller als der Befehl „mehr“ für eine effektive Dateinavigation ist

11 Gründe, warum Linux besser ist als Windows

Linux vs. Mac:7 Gründe, warum Linux die bessere Wahl ist als Mac

Warum wird select unter Linux verwendet

Warum ist Kernel Shared Memory 0 auf Ubuntu 12.04?

Wie liest man Oom-Killer-Syslog-Meldungen?