Ja, mmap erstellt ein Mapping. Es liest normalerweise nicht den gesamten Inhalt dessen, was Sie in den Speicher gemappt haben. Wenn Sie dies tun möchten, können Sie den Systemaufruf mlock/mlockall verwenden, um den Kernel dazu zu zwingen, den Inhalt des Mappings, falls zutreffend, in den RAM einzulesen.
Nein, ja, vielleicht. Es kommt darauf an.
Anruf mmap
allgemein bedeutet nur, dass für Ihre Anwendung der Inhalt der zugeordneten Datei ihrem Adressraum als ob zugeordnet wird die Datei wurde dort geladen. Oder, als ob die Datei wirklich im Speicher existierte, als ob sie ein und dieselbe wären (was beinhaltet, dass Änderungen auf die Festplatte zurückgeschrieben werden, vorausgesetzt, Sie haben Schreibzugriff).
Nicht mehr und nicht weniger. Es hat keine Vorstellung davon, etwas zu laden, noch weiß die Anwendung, was dies bedeutet.
Eine Anwendung hat keine wirkliche Kenntnis von so etwas wie Speicher, obwohl das virtuelle Speichersystem es so erscheinen lässt. Der Speicher, den eine Anwendung „sehen“ (und darauf zugreifen) kann, kann dem tatsächlichen physischen Speicher entsprechen oder auch nicht, und dieser kann sich im Prinzip jederzeit ohne vorherige Warnung und ohne offensichtlichen Grund (der Ihrer Anwendung offensichtlich ist) ändern.
Abgesehen davon, dass möglicherweise eine kleine Verzögerung aufgrund eines Seitenfehlers auftritt, ist sich eine Anwendung (im Prinzip) überhaupt nicht bewusst, dass so etwas passiert, und hat wenig oder keine Kontrolle darüber.
Anwendungen laden im Allgemeinen Seiten aus zugeordneten Dateien (einschließlich der ausführbaren Hauptdatei!) Bei Bedarf, wenn ein Fehler auftritt. Ein Betriebssystem versucht jedoch normalerweise, Daten spekulativ vorab abzurufen, um die Leistung zu optimieren.
In der Praxis wird mmap
aufgerufen wird sofort beginnen zum (asynchronen) Vorabruf von Seiten vom Beginn der Zuordnung bis zu einer bestimmten implementierungsspezifischen Größe. Das heißt, bei kleinen Dateien wäre die Antwort im Prinzip "ja" und bei größeren Dateien "nein".
Allerdings mmap
blockiert nicht, um auf den Abschluss des Readahead zu warten, was bedeutet, dass Sie nicht garantieren können, dass sich eine der Dateien unmittelbar nach mmap
im RAM befindet Rücksendungen (nicht, dass Sie diese Garantie sowieso zu jeder Zeit haben!). Insofern lautet die Antwort "vielleicht".
Als ich das letzte Mal unter Linux nachgesehen habe, war die Standard-Prefetch-Größe 31 Blöcke (~ 127 KB) - aber dies hat sich möglicherweise geändert, außerdem ist es ein einstellbarer Parameter. Wenn Seiten in der Nähe oder am Ende des vorab abgerufenen Bereichs berührt werden, werden weitere Seiten asynchron vorab abgerufen.
Wenn Sie MADV_RANDOM
angedeutet haben bis madvise
, Prefetching ist "weniger wahrscheinlich", unter Linux wird Prefetch vollständig deaktiviert.
Geben Sie andererseits den MADV_SEQUENTIAL
an Hinweis wird asynchron "aggressiver" vorab abgerufen, beginnend am Anfang der Zuordnung (und kann aufgerufene Seiten schneller verwerfen). Unter Linux bedeutet "aggressiver" doppelt so viel wie normal.
Gib den MADV_WILLNEED
an hint schlägt vor (aber garantiert nicht), dass alle Seiten im angegebenen Bereich so schnell wie möglich geladen werden (da Sie sagen, dass Sie darauf zugreifen werden). Das Betriebssystem kann dies ignorieren, aber unter Linux wird es eher als Befehl denn als Hinweis behandelt, bis zum maximalen RSS-Limit des Prozesses und einem von der Implementierung festgelegten Limit (wenn ich mich richtig erinnere, 1/2 der Menge an physischem RAM). ).
Beachten Sie, dass MADV_DONTNEED
ist unter Linux wohl falsch implementiert. Der Hinweis wird nicht in der von POSIX vorgegebenen Weise interpretiert, d.h. Sie sind damit einverstanden, dass Seiten im Moment ausgelagert werden, sondern dass Sie sie verwerfen wollen . Was für schreibgeschützte zugeordnete Seiten keinen großen Unterschied macht (außer einer kleinen Verzögerung, die Sie sagten, wäre in Ordnung), aber es ist sicher von Bedeutung für alles andere.
Insbesondere mit MADV_DONTNEED
zu denken, dass Linux nicht benötigte Seiten freigibt, nachdem das Betriebssystem sie faul auf die Festplatte geschrieben hat, ist nicht so, wie die Dinge funktionieren ! Sie müssen explizit synchronisieren oder sich auf eine Überraschung vorbereiten.
Nachdem Sie readahead
angerufen haben im Dateideskriptor vor dem Aufruf von mmap
(oder alternativ, nachdem die Datei zuvor gelesen/geschrieben wurde), wird der Inhalt der Datei in der Praxis in der Tat sofort im RAM sein.
Dies ist jedoch nur ein Implementierungsdetail (Unified Virtual Memory System) und unterliegt dem Speicherdruck auf dem System.
Rufen Sie mlock
an wird - sofern es gelingt - die angeforderten Seiten sofort in den Arbeitsspeicher laden. Es blockiert, bis alle Seiten physisch vorhanden sind, und Sie haben die Garantie, dass die Seiten im RAM verbleiben, bis Sie sie entsperren.
Es gibt Funktionen zum Abfragen (
mincore
), ob einige oder alle Seiten in einem bestimmten Bereich gerade vorhanden sind, und Funktionen, um dem Betriebssystem mitzuteilen, was Sie möchten zu sehen, dass dies ohne harte Garantien geschieht (madvise
) und schließlich eine Funktionalität, um zu erzwingen, dass eine begrenzte Teilmenge von Seiten im Speicher vorhanden ist (mlock
) für privilegierte Prozesse. Dies ist möglicherweise nicht der Fall, sowohl aufgrund fehlender Berechtigungen als auch aufgrund der Überschreitung von Kontingenten oder der Menge an vorhandenem physischem RAM.
Standardmäßig konfiguriert mmap() nur das Mapping und die Rückgabe (schnell).
Linux hat (mindestens) die Option MAP_POPULATE (siehe 'man mmap'), die genau das tut, worum es in Ihrer Frage geht.