2014-10-19 7 views
6

Ich habe nicht viel Erfahrung mit Memory-Mapped I/O, aber nach dem sie zum ersten Mal mit an Ich bin fassungslos, wie schnell sie sind. In meinen Leistungstests sehe ich, dass das Lesen von im Speicher abgelegten Dateien 30 Mal schneller ist als das Lesen von normalem C++ - Standard.Warum ist das Lesen aus einer Memory-Mapped-Datei so schnell?

Meine Testdaten sind eine 3-GB-Binärdatei, sie enthält 20 große Gleitkomma-Arrays mit doppelter Genauigkeit. Die Art und Weise, wie mein Testprogramm strukturiert ist, rufe ich die Lesemethode eines externen Moduls auf, die speicherprogrammierte I/O hinter den Kulissen verwendet. Jedes Mal, wenn ich die read-Methode aufruft, gibt dieses externe Modul einen Zeiger und eine Größe der Daten zurück, auf die der Zeiger zeigt. Nach der Rückkehr von dieser Methode rufe ich memcpy auf, um den Inhalt des zurückgegebenen Puffers in ein anderes Array zu kopieren. Da ich ein Memcpy mache, um Daten aus der Memory-Mapped-Datei zu kopieren, erwartete ich, dass die Memory-Mapped-Reads nicht wesentlich schneller als normale Stdio sind, aber ich bin erstaunt, dass es 30x schneller ist.

Warum aus einer Memory-Mapped-Datei liest so schnell?

PS: Ich benutze eine Windows-Maschine. Ich habe meine E/A-Geschwindigkeiten gemessen, und die maximale Plattentransferrate meines Geräts liegt bei 90 MiB/s.

+0

Sie können die Antworten finden [hier] (http://stackoverflow.com/questions/192527/what-are-the-advantages-of-memory-maped-files) –

+0

@SteveLorimer: Ich habe diese Seite vorher gelesen zum Posten. Wenn die Daten aus dem Thread nicht bereits im Speicher vorhanden sind, muss das Betriebssystem die Daten von der Festplatte abrufen. Was ich in meinem Test sehe, ist, dass es keinen Platten-I/O gibt, der einer 3GB Datenübertragung entsprechen würde, ich sehe nur eine Übertragung, die sich auf 2630 Bytes beläuft. Wenn ich jedoch den Inhalt des gemerkten Arrays untersuche, stimmen sie mit dem erwarteten Datenbyte mit dem Byte überein. – DigitalEye

+6

Standard-Benchmark-Gefahr. [Schau hier] (http://superuser.com/questions/417057/is-there-a-way-to-reset-windows-file-cache). –

Antwort

9

Die OS-Kernroutinen für IO, wie Lese- oder Schreibaufrufe, sind immer noch nur Funktionen. Diese Funktionen werden geschrieben, um Daten in den/aus dem Benutzerraumpuffer in eine Kernelraumstruktur und dann in ein Gerät zu kopieren. Wenn Sie bedenken, dass es einen Benutzerpuffer, einen IO-Bibliothekspuffer (zum Beispiel stdio buf), einen Kernel-Puffer und dann eine Datei gibt, können die Daten möglicherweise 3 Kopien durchlaufen, um zwischen Ihrem Programm und dem Datenträger zu gelangen. Die E/A-Routinen müssen auch robust sein, und schließlich verursachen die sys-Aufrufe selbst eine Latenz (Einfangen zum Kernel, Kontextwechsel, Aufwachen wieder aufholen).

Wenn Sie eine Datei im Speicher ablegen, werden Sie einen Großteil davon überspringen und Pufferkopien vermeiden. Wenn Sie die Datei effektiv wie ein großes virtuelles Array behandeln, aktivieren Sie den Direktzugriff, ohne den Syscall-Overhead zu durchlaufen. So verringern Sie die Latenz pro E/A. Wenn der ursprüngliche Code ineffizient ist (viele kleine zufällige E/A-Aufrufe), wird der Overhead sogar reduziert drastischer.

Die Abstraktion eines virtuellen Speichers, Multiprocessing OS hat einen Preis, und das ist es.

Sie können IO in einigen Fällen jedoch verbessern, indem Sie die Pufferung in Fällen deaktivieren, in denen die Performance beeinträchtigt wird, z. B. große zusammenhängende Schreibvorgänge. Darüber hinaus kann die Leistung von speicherprogrammierten IOs jedoch nicht verbessert werden das Betriebssystem insgesamt.

+0

So wäre es fair zu sagen, dass in meinem Fall, die Daten also eine Kopie direkt von der Platte zu meinem Array gingen im Gegensatz zu drei, die Sie beschreiben: Disk-Puffer auf Kernel, Kernel-Puffer zu i/o-Puffer, und schließlich I/O-Puffer in den Speicher meines Programms? – DigitalEye

+1

Ja. Auch wenn der Kernel Ihre Datei auf eine Reihe von Seiten abbildet und die Seiten nicht existieren (noch nicht resident), wird der Kernel einen Seitenfehler verursachen und diese Seiten direkt lesen. – codenheim

Verwandte Themen