Jak sprawić, by system Windows działał tak szybko jak Linux do kompilowania C ++?

142

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.

gman
źródło
5
Nie wiem dlaczego, ale jest to znana różnica w charakterystyce wydajności systemów Windows i Linux. Linux jest DUŻO lepszy niż Windows w radzeniu sobie z mnóstwem plików w jednym katalogu, być może to tylko NTFS vs ext4 / cokolwiek? Możliwe również, że odpowiednik pamięci podręcznej dentry w systemie Windows w systemie Windows nie jest tak dobry.
Spudd86
73
Dlaczego to zostało zamknięte? „Nie być konstruktywnym” ??! Uważam, że jest to dość istotne dla programistów.
Nils
3
To pytanie zawiera fakty i może być poparte dowolną liczbą faktów, odniesień, czegokolwiek. Samo myślenie, że tytuł wydaje się kontrowersyjny, nie powinno powstrzymać nas przed omówieniem problemu, o którym od dawna nie mówi się zbyt wiele. Sam będąc wieloletnim użytkownikiem systemu Windows, chciałbym zadać to pytanie i mam nadzieję, że w każdej chwili uzyskam przydatne odpowiedzi. Otwórz ponownie pytanie, chyba że możesz przedstawić faktyczne dowody na to, że pytanie jest z natury dyskusyjne i nie jest poparte faktami. W przeciwnym razie jesteś tylko moderatorem.
Halil Özgür
2
@ HalilÖzgür: OK, Twój komentarz skłoniło mnie, aby spojrzeć na historię wersji - oryginalny tytuł pytanie było pytaniem coś takiego. To może bardzo dobrze być powód (nie głosować do końca), ponieważ nie był post przez kogoś wyraźnie urażony oryginalnego tytułu i zaczął szaleje, który został następnie usunięty, co prowadzi do zamknięcia na to pytanie jest. Tytuł był edytowany od tamtego czasu, więc myślę, że możemy iść. Ponownie otwarte. Pamiętaj, że nadal powinieneś starać się nie omawiać tego pytania ... ponieważ PO szuka odpowiedzi, udziela odpowiedzi, nic więcej.
BoltClock
2
Byłoby wspaniale, gdyby ktoś taki jak @ raymond-chen włączył się z pewnymi spostrzeżeniami - jeśli pytanie pozostaje techniczne i oferuje wystarczająco jasne dane / fakty, aby odtworzyć problem.
Benjamin Podszun,

Odpowiedzi:

32

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ę).

  1. 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.

  2. 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.

  3. 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.

Noufal Ibrahim
źródło
Czy mógłbyś trochę rozwinąć temat # 2? To dość zaskakujące - czy to dlatego, że jądro nie buforuje danych na dysku RAM, czy coś takiego?
user541686
2
Jeśli przydzielisz część pamięci jako ramdysk, jądro nie będzie mogło go buforować ani używać do niczego innego. W efekcie załamujesz mu rękę i zmuszasz go do zużywania mniejszej ilości pamięci dla własnych algorytmów. Moja wiedza jest empiryczna. Straciłem wydajność, gdy korzystałem z RAMdysku do kompilacji.
Noufal Ibrahim
1
„O ile nie pojawi się [ekspert w określonym temacie], nie dostaniesz nic więcej niż tylko stronnicze komentarze ... i spekulacje”: czym różni się to od wszelkich innych pytań?
Dolph
1
Ten, dzięki tematowi Win vs. Lin, jest bardziej magnesem dla fanów. Również pytanie jest raczej niuansowe w przeciwieństwie do bezpośrednich, które wymagają tylko poleceń lub metod użycia.
Noufal Ibrahim
Link w # 1 nie jest już aktywny.
alkasm
28

Kilka pomysłów:

  1. Wyłącz nazwy 8.3. Może to mieć duży wpływ na dyski z dużą liczbą plików i stosunkowo małą liczbą folderów:fsutil behavior set disable8dot3 1
  2. Użyj więcej folderów. Z mojego doświadczenia wynika, że ​​NTFS zaczyna zwalniać z ponad 1000 plików na folder.
  3. Włącz kompilacje równoległe za pomocą programu MSBuild; wystarczy dodać przełącznik „/ m”, a automatycznie uruchomi jedną kopię programu MSBuild na rdzeń procesora.
  4. Umieść swoje pliki na dysku SSD - bardzo pomaga w przypadku losowych operacji we / wy.
  5. Jeśli średni rozmiar pliku jest znacznie większy niż 4 KB, rozważ przebudowanie systemu plików z większym rozmiarem klastra, który w przybliżeniu odpowiada średniemu rozmiarowi pliku.
  6. Upewnij się, że pliki zostały zdefragmentowane. Pofragmentowane pliki powodują wiele wyszukiwań dysków, co może kosztować 40-krotnie większą przepustowość. Użyj narzędzia „contig” firmy sysinternals lub wbudowanego defragmentatora systemu Windows.
  7. Jeśli średni rozmiar pliku jest mały, a partycja, na której się znajdujesz, jest stosunkowo pełna, możliwe, że używasz pofragmentowanego pliku MFT, co jest niekorzystne dla wydajności. Ponadto pliki mniejsze niż 1K są przechowywane bezpośrednio w MFT. Wspomniane powyżej narzędzie „contig” może pomóc lub może być konieczne zwiększenie rozmiaru MFT. Następujące polecenie podwoi go, do 25% objętości: fsutil behavior set mftzone 2Zmień 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.
  8. Wyłącz czas ostatniego dostępu: fsutil behavior set disablelastaccess 1
  9. Wyłącz usługę indeksowania
  10. Wyłącz oprogramowanie antywirusowe i antyspyware lub przynajmniej ustaw odpowiednie foldery tak, aby były ignorowane.
  11. Umieść swoje pliki na innym dysku fizycznym niż system operacyjny i plik stronicowania. Korzystanie z oddzielnego dysku fizycznego umożliwia systemowi Windows korzystanie z równoległych operacji we / wy na obu dyskach.
  12. Przyjrzyj się flagom swojego kompilatora. Kompilator Windows C ++ ma mnóstwo opcji; upewnij się, że używasz tylko tych, których naprawdę potrzebujesz.
  13. Spróbuj zwiększyć ilość pamięci używanej przez system operacyjny dla buforów puli stronicowanej (najpierw upewnij się, że masz wystarczającą ilość pamięci RAM): fsutil behavior set memoryusage 2
  14. Sprawdź dziennik błędów systemu Windows, aby upewnić się, że nie występują sporadyczne błędy dysku.
  15. Spójrz na liczniki wydajności związane z dyskami fizycznymi, aby zobaczyć, jak zajęte są Twoje dyski. Długie kolejki lub długi czas transferu to zły znak.
  16. Pierwsze 30% partycji dysku jest znacznie szybsze niż reszta dysku pod względem surowego czasu transferu. Węższe partycje również pomagają skrócić czas wyszukiwania.
  17. Czy używasz RAID? Jeśli tak, być może będziesz musiał zoptymalizować wybór typu RAID (RAID-5 nie nadaje się do operacji intensywnego zapisu, takich jak kompilacja)
  18. Wyłącz wszystkie usługi, których nie potrzebujesz
  19. Defragmentuj foldery: skopiuj wszystkie pliki na inny dysk (tylko pliki), usuń oryginalne pliki, skopiuj wszystkie foldery na inny dysk (tylko puste foldery), a następnie usuń oryginalne foldery, zdefragmentuj oryginalny dysk, najpierw skopiuj strukturę folderów , a następnie skopiuj pliki. Kiedy system Windows tworzy duże foldery, jeden plik na raz, foldery są pofragmentowane i powolne. („kontig” też powinien pomóc)
  20. Jeśli jesteś związany we / wy i masz wolne cykle procesora, spróbuj włączyć kompresję dysku. Może zapewnić znaczne przyspieszenie w przypadku wysoce kompresowalnych plików (takich jak kod źródłowy), z pewnym kosztem procesora.
RickNZ
źródło
1
Nawet gdybyś zrobił te wszystkie rzeczy, nie zbliżyłbyś się do wydajności Linuksa. Wypróbuj poniższy test i opublikuj swój czas, jeśli się nie zgadzasz.
b7kich
6
Potrzebujemy lepszego wzorca. Mierzenie czasu potrzebnego do wyliczenia folderu nie jest zbyt przydatne, IMO. NTFS jest zoptymalizowany pod kątem czasów wyszukiwania pojedynczych plików, ze strukturą btree. W Linuksie (ostatnio widziałem), aplikacja może odczytać cały folder za pomocą jednego wywołania systemowego i iterować przez wynikową strukturę w całości w kodzie użytkownika; Windows wymaga oddzielnego wywołania sys dla każdego pliku. Tak czy inaczej, kompilatory nie powinny czytać całego folderu…
RickNZ
3
Zatem to, co opisujesz, jest właśnie problemem. Wybór innego testu porównawczego nie rozwiązuje problemu - po prostu odwracasz wzrok.
b7kich
2
Pytanie dotyczyło optymalizacji czasu kompilacji. Czasy wyliczania folderów nie dominują w czasie kompilacji w systemie Windows, nawet w przypadku dziesiątek tysięcy plików w folderze.
RickNZ
1
Po wprowadzeniu niektórych z sugerowanych powyżej zmian, drugie uruchomienie "ls -R" dla drzewa chromu zajmuje mi 4,3 sekundy (w porównaniu z 40 sekundami w OP). „dir / s” trwa około sekundy. Przejście na dysk SSD nie pomogło w samym wyliczaniu, ale podejrzewam, że pomoże przy kompilacjach.
RickNZ
25

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)

Agent_L
źródło
6
Testowanie skróciło o 4 sekundy w porównaniu z poprzednimi 36. Wciąż okropne w porównaniu do 0,6 sekundy na moim VM z systemem Linux
b7kich.
21

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.

Społeczność
źródło
17

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.

bfrog
źródło
poważnie? Masz na myśli, że powinienem wypróbować maszynę wirtualną jako urządzenie programistyczne? Brzmi dziwnie ... jakiej maszyny wirtualnej używasz?
Martin Booka Weser
8
Przetestowałem powyższy scenariusz z maszyną wirtualną Ubuntu 11.04 uruchomioną na mojej stacji roboczej z systemem Windows 7. 0,6 sekundy dla maszyny wirtualnej z systemem Linux, 36 sekund dla mojej stacji roboczej z systemem Windows
b7kich
2
Jeśli używasz virtualbox i skonfigurujesz dysk współdzielony, możesz zasadniczo przyspieszyć swoje kompilacje za darmo.
orlp
Sformułowanie tutaj jest bardzo mylące, ale zakładam, że oznacza to maszynę wirtualną hostowaną z systemem Windows z systemem Linux, a nie maszynę wirtualną z systemem Windows hostowaną w systemie Linux ... co jest interesujące, ale moje pierwsze - dosłowne - przeczytanie tego sugeruje, że uruchamianie systemu Windows w skompilowana maszyna wirtualna hostowana w systemie Linux zapewnia wyższą prędkość niż natywne uruchamianie systemu Windows - i to byłoby naprawdę coś.
underscore_d
@underscore_d, widziałem to coś , gdzie Windows na maszynie wirtualnej działa znacznie szybciej niż na prawdziwym sprzęcie. Prawdopodobnie dlatego, że Linux powiedział Windowsowi, że działa na prawdziwym dysku, podczas gdy Linux w rzeczywistości przeprowadzał agresywne buforowanie za kulisami. Na przykład instalacja systemu Windows na maszynie wirtualnej również przebiegła niesamowicie szybko. To było w czasach XP, ale byłbym zaskoczony, gdyby dzisiaj była duża różnica.
Prof. Falken,
17

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.

  1. 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.

  2. 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.

  3. 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ść.

  4. 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.

TomOnTime
źródło
6
Stwierdzenie, że przyczyna jest „kulturowa, a nie techniczna”, nie odpowiada tak naprawdę na pytanie. Oczywiście istnieje co najmniej jeden techniczny powód, dla którego niektóre operacje są wolniejsze w systemie Windows niż w systemie Linux. Otóż, kwestie kulturowe mogą wyjaśnić, dlaczego ludzie podjęli techniczne decyzje; ale to jest strona z pytaniami technicznymi. Odpowiedzi powinny obejmować techniczne powody, dla których jeden system jest wolniejszy od drugiego (i co można zrobić, aby poprawić sytuację), a nie nie dające się udowodnić domysły dotyczące kultury.
Brian Campbell
Wydaje się, że nie zawiera wielu informacji technicznych. Przeważnie okrężne. Myślę, że jedynym sposobem uzyskania prawdziwych informacji technicznych jest przyjrzenie się różnicom między dwoma kompilatorami, systemami kompilacji itp. Itp.
surfasb
Aplikacje systemu Windows mają tendencję do otwierania jednego dużego pliku i utrzymywania go otwartego przez długi czas - robi to wiele aplikacji UNIX. Serwery, mój Emacs itp.
Noufal Ibrahim,
Nie sądzę, aby emacs przechowywał otwarte pliki przez długi czas, niezależnie od tego, czy są duże, czy małe. Z pewnością nie zapisuje w środku pliku, aktualizując go tak, jak robiłaby to baza danych.
TomOnTime
… A serwery też tego nie robią. Ich funkcje w systemach * nix są zwykle podzielone na wiele małych modułów, przy czym rdzeń serwera jest zasadniczo pustą powłoką.
widma
7

Łą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 /smają więcej wspólnego z zapisywaniem danych wyjściowych niż mierzeniem rzeczywistego pliku wydajność przemierzania. Nawet dir /s /b > nuldziała wolno na moim komputerze z ogromnym katalogiem.

MSN
źródło
6

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).

Átila Neves
źródło
5

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.exeproces dla każdego wiersza przepisu, powodując różnicę w wydajności między systemami Windows i Linux!

Zgodnie z dokumentacją GNU make

.ONESHELL:

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!

V15I0N
źródło
4

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:

  • Windows Home Premium 7 (8 GB RAM) w systemie plików NTFS: 32 sekundy
  • Ubuntu 11.04 Linux (2 GB RAM) w systemie plików NTFS: 10 sekund
  • Ubuntu 11.04 Linux (2 GB RAM) na ext4: 0,6 sekundy

Do testów wyciągnąłem źródła chromu (oba pod win / linux)

git clone http://github.com/chromium/chromium.git 
cd chromium
git checkout remotes/origin/trunk 

Aby zmierzyć czas biegania

ls -lR > ../list.txt ; time ls -lR > ../list.txt # bash
dir -Recurse > ../list.txt ; (measure-command { dir -Recurse > ../list.txt }).TotalSeconds  #Powershell

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.

b7kich
źródło
1
Po wykonaniu kilku zmian, które opisuję w mojej odpowiedzi dla systemu Windows, wykonanie powyższego testu "ls -lR" na drzewie chromu zajęło 19,4 sekundy. Jeśli zamiast tego użyję "ls -UR" (co nie daje statystyk plików), czas spada do 4,3 sekundy. Przeniesienie drzewa na dysk SSD nie przyspieszyło niczego, ponieważ dane pliku są buforowane przez system operacyjny po pierwszym uruchomieniu.
RickNZ
Dzięki za udostępnienie! Pomimo solidnej poprawy o współczynnik 10 w porównaniu ze scenariuszem `` po wyjęciu z pudełka '' systemu Windows 7, jest to nadal o czynnik 10 gorszy niż Linux / ext4.
b7kich
Myślałem, że celem OP było poprawienie wydajności systemu Windows, prawda? Ponadto, jak napisałem powyżej, „dir / s” pojawia się za około sekundę.
RickNZ
3

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ę!

OpenNingia
źródło
1

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.

V15I0N
źródło
0

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ę).

V15I0N
źródło