2010-09-20 13 views
14

Pracuję nad aplikacją, która sekwencyjnie zapisuje duży plik (i nie czyta wcale) i chciałbym użyć posix_fadvise() do optymalizacji zachowania systemu plików.Co posix_fadvise() argumentuje za sekwencyjnym zapisywaniem plików?

Opis funkcji na stronie podręcznika sugeruje, że najbardziej odpowiednią strategią będzie POSIX_FADV_SEQUENTIAL. Jednak opis implementacji Linuksa wątpi, że:

Pod Linuksem, POSIX_FADV_NORMAL ustawia okno ponownego sprawdzania na domyślny rozmiar dla urządzenia zabezpieczającego; POSIX_FADV_SEQUENTIAL podwaja ten rozmiar, a POSIX_FADV_RANDOM wyłącza całkowicie plik readahead.

Ponieważ piszę tylko dane (prawdopodobnie również nadpisuję pliki), nie oczekuję żadnych zmian. Czy powinienem wtedy trzymać się mojego POSIX_FADV_SEQUENTIAL, czy raczej użyć POSIX_FADV_RANDOM, aby go wyłączyć?

Co z innymi opcjami, takimi jak POSIX_FADV_NOREUSE? A może w ogóle nie używać do pisania w ogóle posix_fadvise()?

Odpowiedz

5

Wszystko zależy od czasowej lokalizacji danych. Jeśli twoja aplikacja nie potrzebuje danych wkrótce po jej zapisaniu, możesz użyć numeru POSIX_FADV_NOREUSE, aby uniknąć zapisywania w pamięci podręcznej bufora (w podobny sposób, jak flaga O_DIRECT z open()).

+8

Należy pamiętać, że POSIX_FADV_NOREUSE nie jest zaimplementowany w jądrze Linux. – smoors

0

Jeśli chodzi o pisanie, myślę, że można po prostu polegać na programie planującym dyski IO systemu operacyjnego, aby zrobić to, co trzeba.

Należy pamiętać, że chociaż posix_fadvise jest specjalnie po to, aby dać wskazówki jądra dotyczące przyszłych wzorców użycia pliku, jądro ma również inne dane, które mogą mu pomóc.

Jeśli nie otworzy się pliku do odczytu, to będzie musiał tylko odczytać bloki, gdy były częściowo napisane. Jeśli skracasz plik do 0, to nawet nie musisz tego robić (powiedziałeś, że nadpisałeś).

32

Większość flag (np. POSIX_FADV_SEQUENTIAL i POSIX_FADV_RANDOM) to wskazówki, które mogą pomóc w odrodzeniu, a nie pisaniu.

Istnieje kilka porad Linusa here i here dotyczących uzyskania dobrej wydajności zapisu sekwencyjnego. Chodzi o to, aby przełamać ten plik do dużego-owski (8MB) okna, a następnie pętla wokół robi:

  • Wypisz okienka n z write();
  • Zapytanie asynchroniczne zapisu z okna N z sync_file_range(..., SYNC_FILE_RANGE_WRITE)
  • czekać na odpisy z okna N-1, aby zakończyć z sync_file_range(..., SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER)
  • okna Spadek N-1 z Obsługi KlientaSchowek z posix_fadvise(..., POSIX_FADV_DONTNEED)

W ten sposób nigdy nie będziesz mieć więcej niż dwóch wartości danych Windows w pamięci podręcznej stron, ale nadal będziesz zapisywać jądro części strony na dysku podczas wypełniania kolejnej części.

+1

Fantastyczne, to jest to, czego potrzebowałem, aby zrobić utee (https: // github.com/aktau/utee) nie wyrzucaj podręcznej skrzynki, ale trzymaj się szybko. Dzięki! – Aktau

Powiązane problemy