2012-06-21 8 views
5

Ich implementiere cp (Datei kopieren) -Befehl mit mmap(). Dafür habe ich die Quelldatei in MAP_PRIVATE (wie ich gerade lesen will) Modus und Zieldatei im MAP_SHARED-Modus (wie ich den geänderten Inhalt der Zieldatei schreiben muss) zugeordnet.Wie zu deaktivieren Copy-on-Write und Null gefüllt bei Bedarf für mmap()

Während ich dies getan habe, habe ich eine Leistungseinbuße aufgrund von vielen kleineren Seitenfehlern beobachtet, die aus zwei Gründen auftreten. 1) Zero fill on demand beim Aufruf von mmap (MAP_PRIVATE) für die Quelldatei. 2) Kopieren beim Schreiben beim Aufruf von mmap (MAP_SHARED) für die Zieldatei.

Gibt es eine Möglichkeit, Zero-Fill-on-Demand und Copy-on-Write zu deaktivieren?

Danke, Harish

+0

Ich bin überrascht, dass Sie eine Leistungseinbuße für Nullfüllung sehen, wie messen Sie es? Sie möchten COW nicht deaktivieren, da dies für die Funktionsweise des virtuellen Speichers grundlegend ist und die Leistung verbessert. Haben Sie in Betracht gezogen, dass die Verwendung von 'write (2)' für die Kopie effizienter sein könnte? Geben Sie die private Map als Puffer zum Schreiben an. Es vermeidet auch den Schritt der Erweiterung der neuen Datei, da 'write (2)' es für Sie tun wird. – cdarke

+0

Ich messe den kleineren Seitenfehler durch getrusage(). Es zeigt, dass es fast 50000 kleinere Seitenfehler gibt, 1gb Datei mit mmam() zu kopieren (fast 25000 für gelesene mmap (MAP_PRIVATE) und dasselbe für write mmap (MAP_SHARED)). Ja, ich habe überprüft write (2) ist effizienter als mmap() zum Kopieren, aber ich denke mmap() kann effizient sein, wenn wir Zero-fill-on-demand und Copy-on-write deaktivieren. – Harish

+0

Harish, check 'madvice()' und 'mlock()' syscalls. Sie können sich auf die Anzahl der Seitenfehler auswirken. Überprüfen Sie für eine schnelle Dateikopie syscall 'sendfile()'. – osgx

Antwort

2

Es gibt MMAP_POPULATE Flagge von mmap (2):

http://linux.die.net/man/2/mmap

MAP_POPULATE (seit Linux 2.5.46) Populate (Vorfehler) Seitentabellen für eine Kartierung. Bei einer Dateizuordnung führt dies zu einem Read-Ahead der Datei. Spätere Zugriffe auf das Mapping werden nicht durch Seitenfehler blockiert. MAP_POPULATE wird seit Linux 2.6.23 nur für private Mappings unterstützt.

Es sollte alle Seiten im mmapped-Bereich vorfehlerhaft sein. Es sollte für Frage (1) funktionieren und möglicherweise nicht für Frage (2) funktionieren (geteilt).

+2

Hinweis: 'MAP_POPULATE' bedeutet keine Verzögerungen, wenn Sie das Mapping verwenden (außer es wird durch den Speicherdruck ausgelagert), aber es bedeutet auch, dass der' mmap' Aufruf selbst blockiert, bis die ganze Datei eingelesen ist. Es ist oft besser vermeide 'MAP_POPULATE' zugunsten von' posix_madvise' (http://linux.die.net/man/3/posix_madvise) (oder nicht standardisiert ['madvise'] (http://linux.die.net/ man/2/madvise)) mit 'POSIX_MADV_WILLNEED', was äquivalent zu' MAP_POPULATE' ist, aber nicht blockiert. Sie können die Quelldatei öffnen/zuordnen, sie zum Laden anweisen, und der Hintergrund des Betriebssystems wird in großen Mengen gelesen, anstatt eine fehlerhafte Verarbeitung zu verlangen. – ShadowRanger

+0

Sie könnten beim Lesen von "mmap" blockieren, aber weil das gesamte Einlesen im Voraus geplant ist, wird der Lesevorgang bereits ausgeführt, wenn Sie auf die leere Seite drücken. Sie werden keine neuen E/A-Anfragen live versenden. – ShadowRanger