Testowałem różne metody, aby skrócić czas kompilacji całego mojego projektu w C ++. Obecnie zajmuje to około 5 minut. Eksperymentowałem z distcc, ccache i innymi. Niedawno odkryłem, że jeśli skopiuję cały projekt na dysk RAM, a następnie skompiluję stamtąd, skróci to czas kompilacji do 30% jego oryginalnego - zaledwie 1,5 minuty.
Oczywiście praca z napędu RAM nie jest praktyczna. Czy ktoś wie, w jaki sposób mogę zmusić system operacyjny do przechowywania określonego katalogu w pamięci podręcznej ? Nadal chcę, aby katalog został zsynchronizowany z powrotem na dysk, jak zwykle, ale zawsze chcę również kopię danych w pamięci. czy to możliwe?
EDYCJA:
Jako możliwe rozwiązanie, właśnie pomyśleliśmy o uruchomieniu demona, który działa rsync
co około 10 sekund, aby zsynchronizować dysk z dyskiem RAM. Następnie uruchamiamy kompilację z napędu RAM. rsync
Jest niezwykle szybkie, ale czy to naprawdę działa? Z pewnością system operacyjny mógłby zrobić lepiej ...
źródło
time
podać swoją kompilację i podzielić się z nami wynikiem? Rozwiałoby to pewne kontrowersje.make clean && /usr/bin/time -v make
(nie używaj wbudowanegotime
polecenia bash )time
wbudowany bash (help time
) ma o wiele mniej szczegółów (brak opcji pełnych ) niż czas GNU (man time
) dotyczący I / O, przełączników kontekstu, ...Odpowiedzi:
Oczywistym sposobem przechowywania wielu plików w pamięci podręcznej jest częsty dostęp do nich. Linux jest całkiem dobry w arbitrażu między zamianą a buforowaniem, więc podejrzewam, że zaobserwowana różnica prędkości nie wynika z tego, że system operacyjny nie przechowuje danych w pamięci podręcznej, ale z innej różnicy między użyciem tmpfs a innymi próbami.
Spróbuj obserwować, co robi IO w każdym przypadku. Podstawowym narzędziem do tego jest
iotop
. Przydatne mogą być inne narzędzia; zobacz rozkład obciążenia IO dysku Linux, według ścieżki systemu i / lub procesu? , Jaki program w systemie Linux może mierzyć we / wy w czasie? i inne wątki związane z awarią serwera.Oto kilka hipotez dotyczących tego, co może się dziać. Jeśli wykonasz pomiary, pokaż je, abyśmy mogli potwierdzić lub obalić te hipotezy.
noatime
opcją montowania. Twoje rozwiązanie tmpfs + rsync nigdy nie czyta z dysku twardego, więc nigdy nie musi poświęcać dodatkowego czasu na pisanie.sync()
albo dlatego, że jądro często opróżnia bufory wyjściowe, zapisy potrwają dłużej na dysk twardy niż w tmpfs.źródło
Linux domyślnie używa pamięci RAM jako pamięci podręcznej dysku. Jako demonstrację spróbuj uruchomić
time find /some/dir/containing/a/lot/of/files > /dev/null
dwa razy, drugi raz jest znacznie szybszy, ponieważ wszystkie i-węzły dyskowe są buforowane. Chodzi o to, jak wykorzystać tę funkcję jądra i zatrzymać próbę jej zastąpienia.Chodzi o zmianę
swappiness
. Rozważmy trzy główne typy wykorzystania pamięci: aktywne programy, nieaktywne programy i pamięć podręczna dysku. Oczywiście pamięci używanej przez aktywne programy nie należy zamieniać, a wybór między dwoma innymi jest dość arbitralny. Czy chcesz szybkie przełączanie programów lub szybki dostęp do plików? Niski swappiness woli zachować w pamięci programów (nawet jeśli nie jest używany przez dłuższy czas) i wysokiej swappiness woli zachować więcej pamięci podręcznej dysku (poprzez zamianę nieużywane programy). (skala zamiany wynosi od 0 do 100, a wartość domyślna to 60)Moim rozwiązaniem twojego problemu jest zmiana swapiness na bardzo wysoki (90-95, żeby nie powiedzieć 100) i załadowanie pamięci podręcznej:
Jak się domyślacie, trzeba mieć wystarczającą ilość wolnej pamięci, aby pomieścić w pamięci podręcznej wszystkie pliki źródłowe i pliki obiektów, a także kompilator, dołączone pliki nagłówków, połączone biblioteki, IDE i inne używane programy.
źródło
tmpfs
w tym samym przypadku również zostałby wymieniony.Wymuszanie buforowania nie jest właściwym sposobem na zrobienie tego. Lepiej przechowywać źródła na dysku twardym i kompilować je na tmpfs. Wiele systemów kompilacji, takich jak qmake i CMake, obsługuje kompilacje poza źródłami.
źródło
Te
inosync
dźwięki demon jak to robi dokładnie to, co chcesz, jeśli masz zamiar rsync do ramdysku. Zamiast rsynchronizować co około 10 sekund, używa funkcji inotify Linuksa do rsyncowania, gdy plik się zmienia. Znalazłem go w repozytorium Debiana jakoinosync
pakiet lub jego źródło jest dostępne pod adresem http://bb.xnull.de/projects/inosync/ .źródło
Wydaje mi się, że to działa, jeśli chcę przechowywać niektóre pliki lub wszystkie pliki w określonym katalogu w pamięci podręcznej.
vmtouch wydaje się robić właśnie to. Przykład 5 może być tym, czego potrzebujesz.
Musiałem uruchomić go jako root
sudo
źródło
Biorąc pod uwagę wystarczającą pamięć, twoja kompilacja z ramdysku nie wykonuje operacji we / wy. Może to przyspieszyć wszystko, co czyta lub zapisuje pliki. I / O jest jedną z najwolniejszych operacji. Nawet jeśli wszystko zostanie zapisane w pamięci podręcznej przed kompilacją, nadal masz wejścia / wyjścia do zapisu, chociaż powinny one mieć minimalny wpływ.
Możesz przyspieszyć, wstępnie ładując wszystkie pliki do pamięci podręcznej, ale czas potrzebny na to powinien zostać uwzględniony w całkowitych czasach kompilacji. To może nie dać ci dużej przewagi.
Budowanie obiektów i plików pośrednich w pamięci RAM, a nie na dysku. Robienie przyrostowych kompilacji może przynieść znaczące korzyści przy częstych kompilacjach. W większości projektów wykonuję codzienną czystą kompilację i przyrostowe kompilacje pomiędzy nimi. Kompilacje integracyjne są zawsze kompilacjami czystymi, ale staram się ograniczać je do mniej niż jednej dziennie.
Możesz zwiększyć wydajność, używając partycji ext2 z wyłączonym atime. Twoje źródło powinno mieć kontrolę wersji w kronikowanym systemie plików, takim jak ext3 / 4.
źródło
Jak wspomniano wcześniej, oczywistym sposobem jest odczytanie całej struktury katalogów i zawartości plików, które chcesz buforować.
Możesz to zautomatyzować, pisząc skrypt do monitorowania wyników
vmstat 1
(użyj dowolnego równoważnego narzędzia dla swojego systemu operacyjnego) i zachowaj sumę liczby zapisanych i odczytanych bloków. Gdy suma przekroczy określony próg, przeczytaj wszystkie pliki, które chcesz buforować, zresetuj sumę, a następnie kontynuuj monitorowanie wyjścia vmstat. Aby szybko odczytywać pliki: jeśli twoje drzewo zawiera wiele plików, unikajfind ... -exec cat
zamiast tego wypróbujfind ... -print0 | xargs -0 cat
niestandardowy program, który nie uruchomi cat dla każdego pliku.Monitorowanie We / Wy dysku jest lepsze niż stosowanie ustalonego interwału, ponieważ sygnalizuje, że dane należy czytać częściej lub rzadziej, w zależności od obciążenia We / Wy dysku.
Z powodzeniem korzystałem z tej zautomatyzowanej metody w systemach, w których zawsze potrzebowałem szybkiego odczytu plików indeksu, unikając operacji we / wy dysku twardego. Użyłem również strace do stworzenia listy każdego pliku, do którego uzyskuje się dostęp po zalogowaniu, dzięki czemu mogę utrzymać wszystko w pamięci podręcznej, aby umożliwić szybkie logowanie.
To może nie być najlepsze możliwe rozwiązanie, ale dobrze mi pasowało.
źródło