Wiem, że to nie tyle kwestia programowania, ale jest istotna.
Pracuję nad dość dużym projektem wieloplatformowym . W systemie Windows używam VC ++ 2008. W systemie Linux używam gcc. W projekcie jest około 40 tys. Plików. Windows kompiluje i łączy ten sam projekt od 10x do 40x wolniej niż Linux. Jak mogę to naprawić?
Pojedyncza zmiana przyrostowa kompilacja 20 sekund w systemie Linux i> 3 minuty w systemie Windows. Czemu? Mogę nawet zainstalować „złoty” linker w Linuksie i skrócić ten czas do 7 sekund.
Podobnie git jest 10x do 40x szybszy w Linuksie niż Windows.
W przypadku gita jest możliwe, że git nie używa systemu Windows w optymalny sposób, ale VC ++? Można by pomyśleć, że Microsoft chciałby, aby ich własni programiści byli tak produktywni, jak to tylko możliwe, a szybsza kompilacja przeszłaby długą drogę w tym kierunku. Może próbują zachęcić programistów do C #?
W ramach prostego testu znajdź folder z dużą ilością podfolderów i zrób proste
dir /s > c:\list.txt
w systemie Windows. Zrób to dwa razy i raz drugi bieg, aby działał z pamięci podręcznej. Skopiuj pliki do Linuksa i wykonaj równoważne 2 uruchomienia i czas drugiego uruchomienia.
ls -R > /tmp/list.txt
Mam 2 stacje robocze z dokładnie tymi samymi specyfikacjami. HP Z600 z 12 gigabajtami pamięci RAM, 8 rdzeniami przy 3,0 GHz. W folderze zawierającym ~ 400 tys. Plików Windows zajmuje 40 sekund, Linux zajmuje mniej niż 1 sekundę.
Czy istnieje ustawienie rejestru, które mogę ustawić w celu przyspieszenia systemu Windows? Co daje?
Kilka nieco istotnych linków, związanych z czasem kompilacji, niekoniecznie I / O.
Najwyraźniej w systemie Windows 10 (nie w systemie Windows 7) występuje problem polegający na tym, że zamknięcie procesu powoduje zablokowanie globalnej blokady . Podczas kompilacji z wieloma rdzeniami, a zatem z wieloma procesami, pojawia się ten problem.
Ta
/analyse
opcja może niekorzystnie wpłynąć na perf, ponieważ ładuje przeglądarkę internetową . (Nie dotyczy, ale dobrze wiedzieć)
Odpowiedzi:
O ile nie pojawi się zagorzałego hakera systemów Windows, nie dostaniesz więcej niż komentarze stronników (których nie zrobię) i spekulacje (czego spróbuję).
System plików - Powinieneś spróbować tych samych operacji (w tym
dir
) na tym samym systemie plików. Natknąłem się na to, które testuje kilka systemów plików dla różnych parametrów.Buforowanie. Kiedyś próbowałem uruchomić kompilację w systemie Linux na dysku RAM i stwierdziłem, że jest wolniejsza niż uruchamianie jej na dysku, dzięki temu, jak jądro zajmuje się buforowaniem. Jest to solidny punkt sprzedaży dla Linuksa i może być powodem, dla którego wydajność jest tak inna.
Złe specyfikacje zależności w systemie Windows. Może specyfikacje zależności chromu dla Windows nie są tak poprawne jak dla Linuksa. Może to spowodować niepotrzebne kompilacje po wprowadzeniu niewielkiej zmiany. Być może uda się to sprawdzić za pomocą tego samego zestawu narzędzi kompilatora w systemie Windows.
źródło
Kilka pomysłów:
fsutil behavior set disable8dot3 1
fsutil behavior set mftzone 2
Zmień ostatnią liczbę na 3 lub 4, aby zwiększyć rozmiar o dodatkowe 12,5% przyrosty. Po uruchomieniu polecenia uruchom ponownie, a następnie utwórz system plików.fsutil behavior set disablelastaccess 1
fsutil behavior set memoryusage 2
źródło
NTFS zapisuje czas dostępu do plików za każdym razem. Możesz spróbować go wyłączyć: "fsutil zachowanie set disablelastaccess 1" (restart)
źródło
Problem z Visual C ++ polega na tym, o ile wiem, że optymalizacja tego scenariusza nie jest priorytetem dla zespołu kompilatorów. Ich rozwiązaniem jest użycie funkcji prekompilowanego nagłówka. Właśnie to zrobiły określone projekty systemu Windows. Nie jest przenośny, ale działa.
Co więcej, w systemie Windows zazwyczaj masz skanery antywirusowe, a także narzędzia do przywracania systemu i wyszukiwania, które mogą całkowicie zrujnować czas kompilacji, jeśli monitorują za Ciebie Twój buid folder. Monitor zasobów systemu Windows 7 może pomóc Ci to zauważyć. Mam tutaj odpowiedź z dalszymi wskazówkami dotyczącymi optymalizacji czasu kompilacji vc ++, jeśli naprawdę jesteś zainteresowany.
źródło
Osobiście odkryłem, że uruchomienie maszyny wirtualnej z systemem Windows w systemie Linux zdołało usunąć znaczną część powolności we / wy w systemie Windows, prawdopodobnie dlatego, że maszyna wirtualna systemu Linux wykonywała dużo pamięci podręcznej, czego sam Windows nie był.
Dzięki temu mogłem przyspieszyć kompilację dużego (250Kloc) projektu C ++, nad którym pracowałem, z około 15 minut do około 6 minut.
źródło
Trudność w tym wynika z faktu, że C ++ ma tendencję do rozprzestrzeniania się i procesu kompilacji na wiele małych, pojedynczych plików. W tym Linux jest dobry, a Windows nie. Jeśli chcesz stworzyć naprawdę szybki kompilator C ++ dla Windows, staraj się trzymać wszystko w pamięci RAM i jak najmniej dotykać systemu plików.
W ten sposób stworzysz szybszy łańcuch kompilacji Linuksa C ++, ale jest to mniej ważne w Linuksie, ponieważ system plików już robi za Ciebie wiele z tego dostrajania.
Przyczyną tego jest kultura uniksowa: w przeszłości wydajność systemu plików była znacznie wyższym priorytetem w świecie Uniksa niż w systemie Windows. Nie znaczy to, że nie był to priorytet w systemie Windows, po prostu w systemie Unix miał wyższy priorytet.
Dostęp do kodu źródłowego.
Nie możesz zmienić tego, czego nie możesz kontrolować. Brak dostępu do kodu źródłowego systemu Windows NTFS oznacza, że większość wysiłków zmierzających do poprawy wydajności dotyczyła ulepszeń sprzętowych. Oznacza to, że jeśli wydajność jest wolna, problem można obejść, ulepszając sprzęt: magistralę, nośnik pamięci itd. Możesz zrobić tylko tyle, jeśli musisz obejść problem, a nie go naprawiać.
Dostęp do kodu źródłowego Uniksa (jeszcze przed otwarciem kodu źródłowego) był bardziej rozpowszechniony. Dlatego jeśli chciałbyś poprawić wydajność, powinieneś zająć się tym najpierw w oprogramowaniu (tańsze i łatwiejsze), a następnie w sprzęcie.
W rezultacie na świecie jest wiele osób, które zdobyły doktoraty, studiując system plików Unix i znajdując nowe sposoby na poprawę wydajności.
Unix ma tendencję do tworzenia wielu małych plików; Windows ma tendencję do tworzenia kilku (lub jednego) dużego pliku.
Aplikacje uniksowe zwykle obsługują wiele małych plików. Pomyśl o środowisku programistycznym: wiele małych plików źródłowych, każdy z innym przeznaczeniem. Ostatni etap (linkowanie) tworzy jeden duży plik, ale jest to niewielki procent.
W rezultacie Unix ma wysoce zoptymalizowane wywołania systemowe do otwierania i zamykania plików, skanowania katalogów i tak dalej. Historia prac badawczych dotyczących Uniksa obejmuje dziesiątki lat optymalizacji systemu plików, które poświęcono dużo uwagi poprawie dostępu do katalogów (wyszukiwanie i skanowanie pełnego katalogu), początkowym otwieraniu plików i tak dalej.
Aplikacje systemu Windows mają tendencję do otwierania jednego dużego pliku, utrzymywania go otwartego przez długi czas i zamykania po zakończeniu. Pomyśl o MS-Word. msword.exe (lub cokolwiek innego) otwiera plik raz i dołącza go godzinami, aktualizuje wewnętrzne bloki i tak dalej. Wartość optymalizacji otwierania pliku byłaby stratą czasu.
Historia testów porównawczych i optymalizacji systemu Windows dotyczy tego, jak szybko można czytać lub zapisywać długie pliki. Właśnie to zostaje zoptymalizowane.
Niestety rozwój oprogramowania zmierzał w kierunku pierwszej sytuacji. Do licha, najlepszy system przetwarzania tekstu dla Uniksa (TeX / LaTeX) zachęca do umieszczania każdego rozdziału w innym pliku i # uwzględniania ich wszystkich razem.
Unix koncentruje się na wysokiej wydajności; Windows koncentruje się na wrażeniach użytkownika
Unix uruchomiony w serwerowni: brak interfejsu użytkownika. Jedyne, co widzą użytkownicy, to szybkość. Dlatego priorytetem jest szybkość.
System Windows został uruchomiony na pulpicie: Użytkownicy dbają tylko o to, co widzą, i widzą interfejs użytkownika. Dlatego więcej energii przeznacza się na poprawę interfejsu użytkownika niż na wydajność.
Ekosystem Windows zależy od planowanej dezaktualizacji. Po co optymalizować oprogramowanie, gdy nowy sprzęt jest już za rok lub dwa?
Nie wierzę w teorie spiskowe, ale gdybym wierzył, wskazałbym, że w kulturze Windows jest mniej bodźców do poprawy wydajności. Modele biznesowe Windows zależą od ludzi kupujących nowe maszyny, takie jak w zegarku. (Dlatego cena akcji tysięcy firm ulega zmianie, jeśli MS spóźni się z dostawą systemu operacyjnego lub jeśli Intel przegapi datę premiery chipa). Oznacza to, że istnieje zachęta do rozwiązywania problemów z wydajnością poprzez nakłanianie ludzi do zakupu nowego sprzętu; nie poprawiając prawdziwego problemu: powolnych systemów operacyjnych. Unix wywodzi się ze środowiska akademickiego, w którym budżet jest napięty, a doktorat można uzyskać, wymyślając nowy sposób na przyspieszenie systemów plików; rzadko ktoś ze środowiska akademickiego otrzymuje punkty za rozwiązanie problemu poprzez wydanie zamówienia.
Ponadto, ponieważ Unix jest oprogramowaniem typu open source (nawet jeśli nie był, każdy miał do niego dostęp), każdy znudzony doktorant może czytać kod i zyskać sławę dzięki ulepszaniu go. To się nie zdarza w systemie Windows (MS ma program, który zapewnia naukowcom dostęp do kodu źródłowego Windows, rzadko jest wykorzystywany). Spójrz na ten wybór artykułów związanych z Uniksem: http://www.eecs.harvard.edu/margo/papers/ lub zapoznaj się z historią artykułów Osterhausa, Henry'ego Spencera lub innych. Heck, jedną z największych (i najprzyjemniejszych do oglądania) debat w historii Uniksa była wymiana zdań między Osterhaus i Selzer http://www.eecs.harvard.edu/margo/papers/usenix95-lfs/supplement/rebuttal. html Nie widać, żeby coś takiego działo się w świecie Windows. Może się zdarzyć, że dostawcy będą się wzajemnie poprawiać, ale ostatnio wydaje się to znacznie rzadsze, ponieważ wydaje się, że wszystkie innowacje są na poziomie organów normalizacyjnych.
Tak to widzę.
Aktualizacja: Jeśli spojrzysz na nowe łańcuchy kompilatorów, które wychodzą z Microsoftu, będziesz bardzo optymistyczny, ponieważ wiele z tego, co robią, ułatwia utrzymanie całego łańcucha narzędzi w pamięci RAM i powtarzanie mniejszej ilości pracy. Bardzo imponujące rzeczy.
źródło
Łączenie przyrostowe
Jeśli rozwiązanie VC 2008 jest skonfigurowane jako wiele projektów z wyjściami .lib, należy ustawić opcję „Użyj danych wejściowych zależności od biblioteki”; dzięki temu konsolidator łączy się bezpośrednio z plikami .obj, a nie z .lib. (I faktycznie powoduje przyrostowe łączenie).
Wydajność przemierzania katalogów
Porównywanie indeksowania katalogów na oryginalnym komputerze z indeksowaniem nowo utworzonego katalogu z tymi samymi plikami na innym komputerze jest trochę niesprawiedliwe. Jeśli chcesz równoważnego testu, prawdopodobnie powinieneś zrobić kolejną kopię katalogu na maszynie źródłowej. (Może nadal być powolny, ale może to być spowodowane wieloma czynnikami: fragmentacją dysku, krótkimi nazwami plików, usługami działającymi w tle itp.) Chociaż myślę, że problemy z perf
dir /s
mają więcej wspólnego z zapisywaniem danych wyjściowych niż mierzeniem rzeczywistego pliku wydajność przemierzania. Nawetdir /s /b > nul
działa wolno na moim komputerze z ogromnym katalogiem.źródło
Jestem prawie pewien, że jest to związane z systemem plików. Pracuję nad projektem wieloplatformowym dla systemu Linux i Windows, w którym cały kod jest wspólny, z wyjątkiem przypadków, gdy kod zależny od platformy jest absolutnie niezbędny. Używamy Mercurial, a nie git, więc „Linuksowość” git nie ma zastosowania. Pobieranie zmian z centralnego repozytorium w systemie Windows trwa wiecznie w porównaniu z Linuksem, ale muszę powiedzieć, że nasze komputery z systemem Windows 7 radzą sobie znacznie lepiej niż komputery z systemem Windows XP. Kompilowanie kodu jest jeszcze gorsze w VS 2008. To nie tylko hg; CMake działa również znacznie wolniej w systemie Windows, a oba te narzędzia używają systemu plików bardziej niż cokolwiek innego.
Problem jest tak poważny, że większość naszych programistów pracujących w środowisku Windows nawet nie zawraca sobie głowy tworzeniem przyrostowych kompilacji - odkrywają, że zamiast tego tworzenie jedności jest szybsze.
Nawiasem mówiąc, jeśli chcesz radykalnie zmniejszyć prędkość kompilacji w systemie Windows, zasugerowałbym wspomnianą wcześniej kompilację jedności. Prawidłowa implementacja w systemie kompilacji jest trudna (zrobiłem to dla naszego zespołu w CMake), ale po wykonaniu tej czynności automagicznie przyspiesza działanie naszych serwerów ciągłej integracji. W zależności od tego, ile plików binarnych wypluwa twój system kompilacji, możesz uzyskać poprawę o 1 do 2 rzędów wielkości. Twój przebieg może się różnić. W naszym przypadku myślę, że trzykrotnie przyspieszyło to kompilację Linuksa i Windows około dziesięciokrotnie, ale mamy wiele współdzielonych bibliotek i plików wykonywalnych (co zmniejsza zalety kompilacji jedności).
źródło
Jak budujesz swój duży projekt międzyplatformowy? Jeśli używasz typowych plików makefile dla systemu Linux i Windows, możesz łatwo obniżyć wydajność systemu Windows dziesięciokrotnie, jeśli pliki makefile nie są zaprojektowane do szybkiego działania w systemie Windows.
Właśnie naprawiłem kilka plików makefile projektu wieloplatformowego, używając wspólnych (GNU) plików makefile dla Linuksa i Windows. Make uruchamia
sh.exe
proces dla każdego wiersza przepisu, powodując różnicę w wydajności między systemami Windows i Linux!Zgodnie z dokumentacją GNU make
powinien rozwiązać problem, ale ta funkcja nie jest (obecnie) obsługiwana przez markę Windows. Zatem przepisanie receptur na pojedyncze linie logiczne (np. Poprzez dodanie; \ lub \ na końcu aktualnych linii edytora) działało bardzo dobrze!
źródło
IMHO to wszystko o wydajności we / wy dysku. Rząd wielkości sugeruje, że wiele operacji jest wykonywanych na dysku w systemie Windows, podczas gdy są one obsługiwane w pamięci w systemie Linux, tj. Linux lepiej buforuje. Najlepszą opcją w systemie Windows będzie przeniesienie plików na szybki dysk, serwer lub system plików. Rozważ zakup dysku SSD lub przeniesienie plików na ramdysk lub szybki serwer NFS.
Przeprowadziłem testy przechodzenia przez katalogi i wyniki są bardzo zbliżone do podanych czasów kompilacji, co sugeruje, że nie ma to nic wspólnego z czasem przetwarzania procesora lub algorytmami kompilatora / linkera.
Zmierzone czasy zgodnie z powyższą sugestią podczas przechodzenia przez drzewo katalogów chromu:
Do testów wyciągnąłem źródła chromu (oba pod win / linux)
Aby zmierzyć czas biegania
Wyłączyłem sygnatury czasowe dostępu, mój skaner antywirusowy i zwiększyłem ustawienia menedżera pamięci podręcznej w systemie Windows (> 2 GB pamięci RAM) - wszystko bez zauważalnych ulepszeń. Faktem jest, że po wyjęciu z pudełka Linux działał 50 razy lepiej niż Windows z jedną czwartą pamięci RAM.
Dla każdego, kto chce twierdzić, że liczby są błędne - z jakiegokolwiek powodu - spróbuj i opublikuj swoje wyniki.
źródło
Spróbuj użyć jom zamiast nmake
Pobierz go tutaj: https://github.com/qt-labs/jom
Faktem jest, że nmake używa tylko jednego z twoich rdzeni, jom jest klonem nmake, który wykorzystuje procesory wielordzeniowe.
GNU robi to zaraz po wyjęciu z pudełka dzięki opcji -j, co może być przyczyną jego szybkości w porównaniu z nmake firmy Microsoft.
jom działa poprzez równoległe wykonywanie różnych poleceń make na różnych procesorach / rdzeniach. Spróbuj sam i poczuj różnicę!
źródło
Chcę dodać tylko jedną obserwację przy użyciu make Gnu i innych narzędzi z narzędzi MinGW w systemie Windows: Wydaje się, że rozwiązują nazwy hostów, nawet jeśli narzędzia nie mogą nawet komunikować się przez IP. Domyślam się, że jest to spowodowane procedurą inicjalizacji środowiska wykonawczego MinGW. Uruchomienie lokalnego serwera proxy DNS pomogło mi poprawić szybkość kompilacji za pomocą tych narzędzi.
Wcześniej dostałem dużego bólu głowy, ponieważ prędkość kompilacji spadła o współczynnik 10 lub więcej, gdy równolegle otworzyłem połączenie VPN. W tym przypadku wszystkie te wyszukiwania DNS przeszły przez VPN.
Ta obserwacja może również dotyczyć innych narzędzi do budowania, nie tylko opartych na MinGW i mogła się w międzyczasie zmienić w najnowszej wersji MinGW.
źródło
Niedawno mogłem zarchiwizować inny sposób na przyspieszenie kompilacji o około 10% w systemie Windows przy użyciu Gnu, zastępując mingw bash.exe wersją z win-bash
(Funkcja win-bash nie jest zbyt wygodna, jeśli chodzi o interaktywną edycję).
źródło