2013-02-19 6 views
5

Hypothetisch angenommen, ich möchte das sequentielle Schreiben in eine potenziell sehr große Datei ausführen.Weist madvise (___, ___, MADV_DONTNEED) das Betriebssystem an, auf Festplatte zu schreiben?

Wenn ich eine riesige Region (madv_SEQUENTIAL) auf diese gesamte Region mmap(), dann kann ich in den Speicher in einer relativ effizienten Weise schreiben. Das habe ich gut gemacht.

Jetzt, um verschiedene OS-Ressourcen freizugeben, während ich schreibe, führe ich gelegentlich eine munmap() auf kleine Teile des Speichers, die bereits geschrieben wurden. Meine Sorge ist, dass munmap() und msync() meinen Thread blockieren und darauf warten, dass die Daten physisch auf die Festplatte übertragen werden. Ich kann meinen Autor überhaupt nicht verlangsamen, also muss ich einen anderen Weg finden.

Wäre es besser, madvise (MADV_DONTNEED) auf dem kleinen, bereits beschriebenen Speicherbereich zu verwenden? Ich möchte dem Betriebssystem mitteilen, dass es diesen Speicher langsam auf die Festplatte schreiben soll, und nicht, um meinen aufrufenden Thread zu blockieren.

Die manpage auf madvise() hat dies zu sagen, welche eher zweideutig ist:

MADV_DONTNEED 
Do not expect access in the near future. (For the time being, the 
application is finished with the given range, so the kernel can free 
resources associated with it.) Subsequent accesses of pages in this 
range will succeed, but will result either in re-loading of the memory 
contents from the underlying mapped file (see mmap(2)) or 
zero-fill-on-demand pages for mappings without an underlying file. 
+0

Ich würde das nicht versuchen; 'MADV_DONTNEED' für eine Dateizuordnung kann so interpretiert werden, dass das Betriebssystem * Änderungen an der Datei * wegschmeißen soll. – zwol

+0

@Zack, haben Sie eine Referenz für MADV_DONTNEED Verwerfen von Änderungen in einer Datei? – Anton

+1

@antonm http://man7.org/tlpi/code/online/dist/vmem/madvise_dontneed.c.html hat ein Programm, das es demonstriert (nicht in sich abgeschlossen, leider, aber einfach genug zu modifizieren). Siehe auch https://www.gnu.org/software/libc/manual/html_node/Memory_002dmapped-I_002fO.html ("' MADV_DONTNEED': Die Region wird nicht mehr benötigt. Der Kernel kann diese Seiten freigeben, * wodurch sich Änderungen ergeben die Seiten verloren gehen * "(Hervorhebung meins)) und dieser LKML-Thread von 2005: https://lkml.org/lkml/2005/6/28/188. – zwol

Antwort

0

erstes, madv_sequential ermöglicht aggressiven readahead, so dass Sie es nicht brauchen. Sekunde, OS wird träge Datei-gebackene Speicher sowieso auf Festplatte schreiben, auch wenn Sie nichts tun werden. aber madv_dontneed wird es anweisen, Speicher sofort freizugeben (was Sie "verschiedene os-Ressourcen" nennen). drittens ist es nicht klar, dass das Mapping von Dateien zum sequentiellen Schreiben einen Vorteil hat. Sie werden wahrscheinlich besser bedient werden, indem Sie einfach schreiben (2) (aber verwenden Sie Puffer - entweder manuell oder stdio).

+1

Diese Antwort ist einfach falsch, siehe oben, warum? – Eloff

+0

korrigiert madv_dontneed Teil – pal

11

Nein!

Für Ihr eigenes Gut, bleiben Sie weg von MADV_DONTNEED. Linux wird nicht nehmen Sie dies als einen Hinweis, um Seiten wegzuschmeißen, nachdem Sie sie zurück geschrieben haben, sondern um sie sofort wegzuwerfen. Dies ist kein Fehler, sondern eine bewusste Entscheidung.

Ironischerweise die Argumentation ist, dass die Funktionalität einer zerstörungs MADV_DONTNEED bereits durch msync(MS_INVALIDATE|MS_ASYNC) gegeben ist, MS_ASYNC auf der anderen Seite nicht startet I/O (in der Tat macht es gar nichts, nach der Argumentation, dass schmutzig Seite Writeback funktioniert trotzdem gut), fsync blockiert immer, und sync_file_rangekann blockieren, wenn Sie einige obskure Grenze überschreiten und gilt als "extrem gefährlich" durch die Dokumentation, was auch immer das bedeutet.

So oder so, müssen Sie msync(MS_SYNC) oder fsync (beide Blockierung) oder sync_file_range (möglicherweise Blockierung) von fsync gefolgt, oder Sie wird verlieren Daten mit MADV_DONTNEED. Wenn Sie es sich nicht leisten können zu blockieren, haben Sie leider keine andere Wahl, als dies in einem anderen Thread zu tun.

+2

Ich denke, du meinst 'msync (MS_INVALIDATE ...' anstelle von 'madvise()' – Hasturkun

+0

Das ist richtig, danke. – Damon

+0

@Damon Ihre durchsetzungsfähige Antwort wurde [referenziert] (https://www.youtube. com/watch? v = bg6-LVCHmGM & feature = youtu.be & t = 4426) in [Bryan Cantrills Surge-Rede 2015 über das MADV_DONTNEED-Verhalten von Linux] (https://www.youtube.com/watch?v=bg6-LVCHmGM&feature=youtu.be&t = 3518). – Anon

Verwandte Themen