Memory Mapped Files



  • Hallo,

    ich stehe vor der Aufgabe mehrere große Textdateien (10-50 GB)
    auszuwerten.

    Auf der Suche nach Ansätzen bin ich dabei immer wieder auf den Begriff des Memory Mappings gestoßen. Damit lassen sich einigen Benchmarks zufolge effiziente Auswertungsprogramme schreiben.

    Ich verstehe nur nicht ganz, wie das ganze funktioniert.
    Wenn ich https://en.wikipedia.org/wiki/Memory-mapped_file richtig verstehe, wird ein großer Block virtuellen Speichers verwendet, der auf die Datei (auf der Festplatte) zeigt. Wahrscheinlich mangelt es mir hier schon an den Kenntnissen über Betriebsysteme und Speicherverwaltung, so dass mirt nicht einleuchtet, inwiefern das zu einem schnelleren Zugriff kommt.
    Die Datei liegt ja trotz allem noch auf der Festplatte, die ja langsamer ist als der Hauptspeicher. Oder übershe ich da etwas?

    Falls sich jemand Zeit nehmen würde, mich ein wenig aufzuklären, würde mich das freuen !



  • Es kommt wie immer auf den Fall an.
    Wenn du (wenig) Daten hast, die du nur im RAM manipulierst und in einem Rutsch speicherst oder liest, ist das schnell. Da brauchst du kein MMF!

    Anders sieht die Sache aus, wenn du
    1. große Daten hast (vielleicht so groß, das die nicht ins RAM passen) und/oder
    2. oft Daten innerhalb einer Datei manipulieren/lesen musst.

    Dann bist du mit deinen Festplattenzugriffen langsamer, weil das MMF erstens größere Blöcke lädt/speichert und zweitens selbst entscheidet, wann das passiert.
    Du könntest natürlich den Algorithmus auch selber implementieren, z.B. wann und wie oft du was tatsächlich schreibst/liest. Aber warum, wenn das OS dieses schon eingebaut hat und die Situation anhand der Telemetrie (Cache, Swap, I/O-Last, konkurrierende Prozesse usw.) besser beurteilen kann?

    Wie immer nimmt dir so eine Library oder OS-Funktion nur die Arbeit ab. Magie steckt nicht dahinter. 😉

    Kann auch helfen:
    https://msdn.microsoft.com/en-us/library/ms810613.aspx



  • Anmerken muss man noch, das wenn du in deinem Fall die großen Textdateien nur streamst (in den Hauptspreicher passen die wahrscheinlich nicht?), es vielleicht keinen signifikanten Nachteil ggü. MMF geben wird.

    Gewissheit hast du natürlich nur, wenn du beide Varianten ausprobierst und mit einem Profiler untersuchst.



  • der vorteil den du hast mit MMF ist, dass das OS die resourcen fuer dich verwaltet und somit versuchen wird deinem program moeglichst viel zur verfuegung zu stellen, natuerlich mit anderen programmen ausbalanziert.

    wenn du auf einem system mit 64GB bist, werden automatisch alle daten im ram landen. wenn du hingegen selbst z.b. 4GB cache allokierst, aber das system hat 100GB oder 1GB, hast du in die eine oder andere richtung nachteile.

    das OS wird auch meist selbst versuchen caches fuer die datei anzulegen, das macht es eigentlich nicht wenn du MMF nutzt, da die pages im speicher ja schon ein 'cache' sind.

    wenn du von mehreren instanzen deines programs (oder auch unterschiedlichen programmen) MMF auf die datei machst, ist die chance gut, dass das OS die datei nur einmal mapped und den einzelnen prozessen die pages reinblendet.

    wenn du selbst speicher allokierst, besteht eine gewisse chance (je nach OS), dass der speicher auch ausgelagert wird, falls du den eine zeitlang nicht nutzt, dabei wird der speicher rausgeschrieben und bei page-misses reingelesen. wenn du MMF nutzt, wird nichts rausgeschrieben, die pages werden einfach nur invalidiert (jedenfalls bei read-only).

    aus meiner sicht spricht am meisten fuer MMF, dass sie sehr einfach sind. eigene caches koennen viel overhead bringen beim arbeiten. gerade wenn mehrere threads darauf arbeiten. MMF sind einfach nur ein pointer auf die daten.


  • Mod

    Das Prinzip der Zugriffszeitbeschleunigung kann man sich vorstellen, wie bei dem Inhaltsverzeichnis/Stichwortverzeichnis in einem Buch, etwa eine dicke Linux-Bibel.
    Technisch gesehen, (auch noch) wie eine Art eigener Interrupt für das ganze Hin- und Her.
    https://de.wikipedia.org/wiki/Memory_Mapped_I/O

    Andere Beschleunigungsversuche z.B. durch "Umordnen", Neuordnen oder auch Verkleinern. Wenn man z.B. in einem Audiofile bestimmte charakteristische Passagen sucht (laut, leise, Gesang oder nicht usw.), dann geht das auch mit MP3s.

    ("Umordnung" benutzen z.B. die Demoscener ja auch bis zum Abwinken, und da bekommt man meist auch gleich die Nachteile mit (lange Wartezeit: ja wann startet die S.. denn endlich... 😉 )
    apropos, weil toll und Inspiration für Performance:
    https://www.youtube.com/watch?v=x_izwOdGFlk



  • nachtfeuer schrieb:

    https://de.wikipedia.org/wiki/Memory_Mapped_I/O

    Hat nix mit Memory-Mapped-Files zu tun.
    Bei Memory-Mapped IO geht's darum wie ein Gerätetreiber mit dem Gerät kommuniziert. Mit Files hat das nixe zu tun. Memory-Mapped IO ist zwar toll, aber gar nicht Thema dieses Threads.

    Den Rest deines Beitrags verstehe ich schlicht und ergreifend nicht. Also wo das jetzt sinnvolle Analogien sein sollen oder wo da überhaupt irgend ein Zusammenhang mit MMF sein soll.

    MP3? Demoszene? DAFUQ?



  • @blasser schimmer
    MMF ist super einfach anzuwenden. File in den Speicher (Adressbereich) mappen, und dann einfach auf diesen Speicher (Adressbereich) zugreifen. Direkt so als ob man das File vorher komplett da reingeladen hätte.

    Das OS sorgt dann im Hintergrund dafür, dass der Inhalt der Bereiche auf die man Zugreift auch vom Datenträger in den Speicher geladen, und dann an der jeweiligen Adresse eingeblendet wird. Vollkommen transparent für die Anwendung. Natürlich muss das OS dabei auch ganz normale IOs an den Datenträger schicken und natürlich dauert das auch.

    Allerdings muss man sich keine Strategie ausdenken wann man jetzt welche Bereiche von Datenträger liest, wie viel man "voraus liest" etc. - darum kümmert sich das OS. Das ganze wird von mehr oder weniger schlauen "generischen" Algorithmen erledigt, die halt mehr oder weniger gut darauf optimiert wurden für alle möglichen Programme und deren Zugriffsmuster gut (schnell) zu funktionieren.

    Dadurch bekommt man oft mit sehr einfachen Programmen gute bis sehr gute Performance. Ohne MMF bessere Performance zu bekommen ist in vielen Fällen eine gute Herausforderung.

    ----

    Was man allerdings manchmal liest, nämlich dass MMF "gravierend" schneller sein kann als jedes noch-so-gut optimierte Programm das klassische APIs verwendet, ist mMn. erstklassiger Bullshit.

    Nur ist es oft den Aufwand einfach nicht wert. Bzw. muss man auch einiges Können und an Erfahrung mitbringen wenn man es mit MMF auf einem modernen OS aufnehmen will.

    In einigen Fällen macht es aber durchaus Sinn.
    z.B. wenn man vorab schon weiss dass man für einen Arbeitsschritt sagen wir mal 1000 Blöcke braucht die kreuz und quer in der Datei verstreut liegen. Da macht es Sinn diese 1000 IO-Requests erstmal alle an das OS zu übergeben (als asynchrone IOs), und danach erst darauf zu warten dass alle abgeschlossen werden. Dadurch kann das OS seine IO-Elevator ausspielen und Features des Datenträgers wie NCQ ausreizen.
    In Extremfällen kann es sogar Sinn machen seinen eigenen IO-Scheduler (mit Elevator' und allem drum & dran) zu basteln, und das OS soweit möglich auszuklammern (File-Cache umgehen etc.).

    Damit kann man locker um ein Vielfaches schneller sein als eine naive Implementierung mit MMF.

    Ich schreibe "als eine naive Implementierung mit MMF", weil es natürlich möglich ist dass es MMF APIs gibt mit denen man dem OS auch vorab den "Tip" geben kann, dass man diese 1000 Blöcke jetzt demnächst brauchen wird, so dass das OS wiederrum die Chance hat gut zu optimieren. Ich weiss nicht ob es solche APIs gibt, aber wenn ja, und wenn man sie sinnvoll anwendet, dann wird man auch mit MMF wieder gleichziehen können, oder zumindest in die Nähe des "ohne MMF" Programms kommen.

    ----

    TL;DR

    Ja, MMF ist meist ne gute Sache. Speziell für Projekte wo man nicht monatelang Zeit hat den IO Code zu optmieren und/oder wenn man noch nicht - salopp gesagt - "IO Spezialist" ist.


  • Mod

    hustbaer schrieb:

    @blasser schimmer
    MMF ist super einfach anzuwenden. File in den Speicher (Adressbereich) mappen, und dann einfach auf diesen Speicher (Adressbereich) zugreifen. Direkt so als ob man das File vorher komplett da reingeladen hätte.

    Soweit ich den TO korrekt verstanden habe, war der nicht an deiner emotionalen Bewertung der Softwareprinzips interessiert, sondern wie die Zugriffsbeschleunigung zustande kommt.
    Sehr viel neues als meine beiden Vorredner hast du leider auch nicht geschrieben - geht auch gar nicht, weil auf der einen Seite das stellvertretende Adressierungsprinzip ist, und auf der anderen Seite das Speicher/Systemmanagement des OS. Welche technischen Infos der TO im Einzelnen jetzt noch zusätzlich bräuchte (außer der eigenen Erfahrung durch Herumprobieren oder Testen), müsste genauer spezifiziert werden.



  • @nachtfeuer
    Die eingängliche ungefragte "emotionalen Berwertung" (🙄) macht durchaus einen Sinn, wenn du den Beitrag als ganzes liest.

    Wenn du anderer Meinung bist kann ich auch nix machen - dann verstehst du halt nicht worauf ich hinaus wollte.

    Mich zu kritisieren, weil ich es gewagt habe einen mMn. total unpassenden Beitrag von dir zu kritisieren/hinterfragen, halt ich für total kindisch.



  • Wie kann ich MMF von Java aus verwenden, ohne dafür selbst auf Jave Native Interfaces zurückzugreifen? Bietet Java dafür entsprechende API Funktionen?



  • Bietet sich MMF auch dann an, wenn man eine große Datei komplett parsen und daraus gewonnene und bearbeitete Informationen in einer anderen Datei speichern möchte?



  • Ich wüsste jetzt nicht was dagegen sprechen sollte.



  • hustbaer schrieb:

    Ich wüsste jetzt nicht was dagegen sprechen sollte.

    ein wenig dagegen spricht der verwaltungsaufwand dem man dem OS aufbuergt.
    also fuer den fall dass sich jemand fragt "wieso noch fopen und nicht immer MMF". Ich hab mal an einer engine mitgearbeitet die komplett auf MMF umgestellt wurde, als die datenmenge dann steig (eine CD + installation auf HDD) und windows zudem noch vram etc. verwaltete, wurde es langsammer.
    vielleicht weil manche bereiche linearen speicher brauchen, wenn also windows 1GB fuer pages allokiert, intern als 4kb pages auslegt und dann ein treiber meint sein DMA braucht 64kb pages, dann muss der speicher umkopiert werden.

    auch auf CPU seite kann es ein wenig langsam werden. page-table-cache misses sind zunehmend performance wichtig. 1GB speicher bei 4kb pages sind 262144 page-table-entries. deswegen wurden "caches" ala "translation lookaside buffer" eingefuehrt und in neusten intel CPUs gibt es wohl 3 hierarchieen, wenn ich mich recht entsinne.
    wenn man fuer eine lineare datei diesen cache fuettert, wirft man automatisch andere eintraege raus auf denen man vielleicht arbeiten wollte.

    z.B.: Wenn man also ein riesen text-file indizieren wollte und in eine std::multimap steckt die quer im speicher verstreut ist, kann es sein, dass das extrem langsam wird.

    will niemanden von MMF abhalten, nur sollte man auch negative dinge erwarten.



  • rapso schrieb:

    hustbaer schrieb:

    Ich wüsste jetzt nicht was dagegen sprechen sollte.

    ein wenig dagegen spricht der verwaltungsaufwand dem man dem OS aufbuergt.
    also fuer den fall dass sich jemand fragt "wieso noch fopen und nicht immer MMF". Ich hab mal an einer engine mitgearbeitet die komplett auf MMF umgestellt wurde, als die datenmenge dann steig (eine CD + installation auf HDD) und windows zudem noch vram etc. verwaltete, wurde es langsammer.

    Cool, danke für den Erfahrungsbericht!
    Wie viel langsamer ca.? Also so ganz grob...


Log in to reply