Wydajność systemu Linux / perl mmap

Próbuję zoptymalizować obsługę dużych zestawów danych za pomocą mmap. Zbiór danych jest w zakresie gigabajtów. Pomysł polegał na przeniesieniu całego pliku do pamięci, umożliwiając jednoczesne działanie wielu procesów na zbiorze danych (tylko do odczytu). Jednak nie działa zgodnie z oczekiwaniami.

W ramach prostego testu po prostu zmieniam plik (używając modułu Sys :: Mmap perla, używając sub-mmap, który, jak sądzę, mapuje bezpośrednio do podstawowej funkcji C) i śpię w procesie. Robiąc to, kod spędza ponad minutę, zanim powróci z połączenia mmap, mimo że test nie robi nic - nawet odczytu - z pliku mmap.

Zgaduję, że być może linux wymagał przeczytania całego pliku po pierwszym mmap'owaniu, więc po zmapowaniu pliku w pierwszym procesie (gdy spał), wywołałem prosty test w innym procesie, który próbował odczytać pierwsze kilka megabajtów pliku.

Co zaskakujące, wydaje się, że drugi proces również spędza dużo czasu przed powrotem z połączenia mmap, mniej więcej w tym samym czasie, co przy pierwszym mapowaniu pliku.

Upewniłem się, że używany jest MAP_SHARED i że proces, który mapował plik po raz pierwszy, jest nadal aktywny (że nie zakończył się i że mmap nie został usunięty).

Spodziewałem się, że plik mmapped pozwoli mi na efektywny dostęp wielu pracowników do dużego pliku, ale jeśli każde wywołanie mmap wymaga najpierw przeczytania całego pliku, jest to nieco trudniejsze. Nie testowałem przy użyciu długotrwałych procesów, aby sprawdzić, czy dostęp jest szybki po pierwszym opóźnieniu, ale oczekiwałem użycia MAP_SHARED i wystarczający byłby inny oddzielny proces.

Moja teoria głosiła, że ​​mmap zwróci się mniej więcej natychmiast, a linux załaduje bloki bardziej lub mniej na żądanie, ale zachowanie, które widzę, jest odwrotne, co wskazuje, że wymaga on odczytu całego pliku przy każdym wywołaniu mmap.

Jakiś pomysł, co robię źle, lub jeśli całkowicie źle zrozumiałem, jak ma działać mmap?

questionAnswers(9)

yourAnswerToTheQuestion