2013-02-19 21 views
5

Hipotetycznie, przypuśćmy, że chcę wykonać sekwencyjne zapisywanie do potencjalnie bardzo dużego pliku.Czy madvise (___, ___, MADV_DONTNEED) instruuje system operacyjny, aby leniwie zapisywał na dysk?

Jeśli I mmap() gigantyczny region i madvise (MADV_SEQUENTIAL) na cały region, to mogę pisać do pamięci w stosunkowo efektywny sposób. To mi się udało do pracy.

Teraz, aby zwolnić różne zasoby systemu operacyjnego podczas pisania, od czasu do czasu wykonuję munmap() na małych porcjach pamięci, które zostały już napisane. Obawiam się, że munmap() i msync() zablokują mój wątek, czekając, aż dane zostaną fizycznie przekazane na dysk. Nie mogę zwolnić mojego pisarza, więc muszę znaleźć inny sposób.

Czy lepiej użyć madvise (MADV_DONTNEED) na małym, już napisanym kawałku pamięci? Chcę, żeby system operacyjny zapisał tę pamięć na dysk leniwie i nie blokował mojego wątku wywołującego.

manpage na madvise() ma do powiedzenia, co jest dość niejednoznaczna:

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

Nie spróbowałbym tego; 'MADV_DONTNEED' na mapowaniu pliku może być interpretowane jako oznaczające, że system ma * wyrzucać * zmiany do pliku. – zwol

+0

@Zack, czy masz odniesienie do MADV_DONTNEED, odrzucając zmiany w pliku? – Anton

+1

@antonm http://man7.org/tlpi/code/online/dist/vmem/madvise_dontneed.c.html ma program, który to demonstruje (nie jest samowystarczalny, niestety, ale łatwy do modyfikacji). Zobacz także https://www.gnu.org/software/libc/manual/html_node/Memory_002dmapped-I_002fO.html ("' MADV_DONTNEED': Region nie jest już potrzebny. Jądro może zwolnić te strony, * powodując wszelkie zmiany w strony do zaginięcia * "(podkreślenie moje)) i ten wątek LKML z 2005 roku: https://lkml.org/lkml/2005/6/28/188. – zwol

Odpowiedz

0

pierwszy madv_sequential umożliwia agresywną readahead, więc nie trzeba go. Po drugie, os będzie leniwie zapisywać na dysku brudną pamięć wypalaną plikami, nawet jeśli nic nie zrobisz. ale madv_dontneed poinstruuje go, aby natychmiast zwolnił pamięć (co nazywasz "różnymi zasobami os"). po trzecie, nie jest jasne, czy pliki mmapping do sekwencyjnego zapisu mają jakąkolwiek przewagę. prawdopodobnie będziesz lepszy dzięki napisaniu (2) (ale użyj buforów - ręcznego lub stdio).

+1

Ta odpowiedź jest po prostu błędna, patrz powyżej, dlaczego. – Eloff

+0

poprawiono madv_dontneed część – pal

11

Nie!

Dla twojego dobra, trzymaj się z dala od MADV_DONTNEED. Linux poda , a nie traktuje to jako wskazówkę do odrzucania stron po ich zapisaniu, ale natychmiast je wyrzuca. Nie jest to uważane za błąd, ale za umyślną decyzję.

ironię, rozumowanie jest, że funkcjonalność jest nieniszczących MADV_DONTNEED jest już podane przez msync(MS_INVALIDATE|MS_ASYNC), MS_ASYNC z drugiej strony nie daje się uruchomić I/O (w rzeczywistości, to w ogóle nic nie robi, po uzasadnieniu tego brudny pagebackback działa poprawnie), fsync zawsze blokuje i sync_file_rangemoże blokować, jeśli przekroczysz jakiś niejasny limit i jest uważany za "bardzo niebezpieczny" przez dokumentację, cokolwiek to znaczy.

Tak czy inaczej, musisz msync(MS_SYNC) lub fsync (zarówno blokowanie) lub sync_file_range (ewentualnie blokowanie), a następnie fsync, albo będzie utracić dane z MADV_DONTNEED. Jeśli nie możesz pozwolić sobie na blokowanie, nie masz wyboru, niestety, ale w innym temacie.

+2

Myślę, że masz na myśli 'msync (MS_INVALIDATE ...' zamiast 'madvise()' – Hasturkun

+0

To prawda, dziękuję. – Damon

+0

@Damon twoja asertywna odpowiedź była [referenced] (https://www.youtube. com/watch? v = bg6-LVCHmGM & feature = youtu.be & t = 4426) w [Bryan Cantrill's 2015 Surge rant o zachowaniu MADV_DONTNEED w systemie Linux] (https://www.youtube.com/watch?v=bg6-LVCHmGM&feature=youtu.be&t = 3518). – Anon