2011-01-16 5 views
9

Piszę dużo danych, które nie będą czytane od tygodni - ponieważ mój program uruchamia ilość wolnej pamięci na komputerze (wyświetlana z "bezpłatnym" lub "górnym") spada bardzo szybko, ilość pamięci, której używa moja aplikacja, nie wzrasta - ani ilość pamięci używana przez inne procesy.niebuforowane wejścia/wyjścia w systemie Linux

To prowadzi mnie do przekonania, że ​​pamięć jest pobierana przez pamięć podręczną systemów plików - ponieważ nie mam zamiaru czytać tych danych przez długi czas, mam nadzieję ominąć bufory systemowe, tak, że moje dane są zapisywane bezpośrednio na dysk. Nie mam marzeń o doskonaleniu perf lub byciu super ninja, mam nadzieję wskazać system plików, że nie zamierzam wracać do tej pamięci w najbliższym czasie, więc nie trać czasu na optymalizację dla tych przypadków.

W systemie Windows napotykałem podobne problemy i naprawiłem problem, używając FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH - pamięć komputera nie została wykorzystana przez moją aplikację, a urządzenie było ogólnie bardziej użyteczne. Mam nadzieję na skopiowanie ulepszeń, które widziałem, ale w systemie Linux. W systemie Windows istnieje ograniczenie pisania na elementach o rozmiarach sektorowych, jestem zadowolony z tego ograniczenia dla zmierzonej wartości wzmocnienia.

jest podobny sposób na to w Linuksie?

Odpowiedz

6

Najbliższym odpowiednikiem flagi systemu Windows można wymienić mogę pomyśleć, to otworzyć plik z open(2) flagi O_DIRECT | O_SYNC:

O_DIRECT (Since Linux 2.4.10) 
      Try to minimize cache effects of the I/O to and from this file. In 
      general this will degrade performance, but it is useful in special 
      situations, such as when applications do their own caching. File I/O 
      is done directly to/from user space buffers. The O_DIRECT flag on its 
      own makes at an effort to transfer data synchronously, but does not 
      give the guarantees of the O_SYNC that data and necessary metadata are 
      transferred. To guarantee synchronous I/O the O_SYNC must be used in 
      addition to O_DIRECT. See NOTES below for further discussion. 

      A semantically similar (but deprecated) interface for block devices is 
      described in raw(8). 

pewnik, starając się zrobić badania na tej flagi, aby potwierdzić to, co chcesz Zauważyłem, że this interesting piece mówi, że niebuforowane wejścia/wyjścia są złym pomysłem, a Linus opisuje go jako "uszkodzony mózg". W związku z tym powinieneś używać madvise(), aby poinformować jądro, w jaki sposób buforować strony. YMMV.

2

jak mój program działa ilość wolnej pamięci na maszyna spada bardzo szybko

Dlaczego jest to problem? Wolna pamięć to pamięć, która nie służy żadnemu pożytecznemu celowi. Kiedy jest używany do przechowywania danych w pamięci podręcznej, przynajmniej istnieje szansa, że ​​będzie przydatny.

Jeśli jeden z twoich programów zażąda większej ilości pamięci, pamięci podręczne plików będą pierwszą rzeczą do zrobienia. Linux wie, że może ponownie odczytać te dane z dysku, kiedy tylko zechce, więc po prostu zbierze pamięć i nada jej nowy użytek.

To prawda, że ​​Linux domyślnie czeka około 30 sekund (to jest to, co było używane wcześniej) przed opróżnieniem zapisu na dysk. Możesz przyspieszyć to, dzwoniąc pod numer fsync(). Ale gdy dane zostaną zapisane na dysku, koszt przechowywania cache danych w pamięci jest praktycznie zerowy.

Widząc, jak piszesz do pliku i nie czytasz z niego, Linux prawdopodobnie zgadnie, że dane te najlepiej jest wyrzucić, zamiast innych buforowanych danych. Nie marnuj więc wysiłku na optymalizację, chyba że potwierdzisz, że jest to problem z wydajnością.

+1

to tylko problem, bo efekt jest pamięć podręczna jest używany do czegoś, co nigdy nie zostanie użyte. Pamięć podręczna jest pobierana od innych użytkowników, którzy mogą z nich korzystać i widzę zwiększone operacje we/wy. – stuck

6

Możesz użyć O_DIRECT, ale w takim przypadku musisz sam wykonać blok IO; musisz pisać w wielokrotnościach wielkości bloku FS i na granicach bloków (możliwe, że nie jest to obowiązkowe, ale jeśli nie, jego wydajność zasysa x1000, ponieważ każdy niewyrównany zapis będzie wymagał najpierw odczytu).

Innym znacznie mniej znaczącym sposobem zatrzymywania bloków przy użyciu pamięci podręcznej systemu operacyjnego bez użycia O_DIRECT, jest użycie posix_fadvise (fd, offset, len, POSIX_FADV_DONTNEED). W jądrze Linux 2.6, które go obsługuje, natychmiast odrzuca (czyste) bloki z pamięci podręcznej. Oczywiście musisz najpierw użyć fdatasync() lub podobnych, w przeciwnym razie bloki mogą być nadal brudne i dlatego nie zostaną usunięte z pamięci podręcznej.

To chyba zły pomysł na fdatasync() i posix_fadvise (... POSIX_FADV_DONTNEED) po każdym napisaniu, ale zamiast tego zaczekaj, aż zrobisz rozsądną kwotę (50M, 100M).

Tak w skrócie

  • (po każdym znaczącym fragmencie) z zapisów,
  • połączeń fdatasync następnie posix_fadvise (... POSIX_FADV_DONTNEED)
  • To spowoduje skasowanie danych na dysku i natychmiast je usunąć z pamięci podręcznej systemu operacyjnego, pozostawiając miejsce na ważniejsze rzeczy.

Niektórzy użytkownicy stwierdzili, że rzeczy takie jak szybko rosnące pliki dziennika mogą z łatwością wydmuchać "bardziej przydatne" rzeczy z pamięci podręcznej, co znacznie zmniejsza liczbę trafień w pamięci podręcznej na pudełku, które musi mieć dużo pamięci podręcznej do odczytu , ale także szybko zapisuje logi. Jest to główna motywacja tej funkcji.

Jednak, jak każdy optymalizacji

a) pan nie będzie go trzeba więc

b) nie rób tego (jeszcze)