Szybkie pytanie: jaka jest flaga kompilatora, która pozwala g ++ na tworzenie wielu własnych instancji w celu szybszego kompilowania dużych projektów (na przykład 4 pliki źródłowe naraz dla wielordzeniowego procesora)?
Czy to naprawdę pomoże? Wszystkie moje zadania kompilacji są powiązane we / wy, a nie z procesorem.
Brian Knoblauch
5
Nawet jeśli są one ograniczone we / wy, prawdopodobnie można utrzymać większe obciążenie we / wy, gdy występują ciężkie bity procesora (przy tylko jednej instancji g ++ wystąpią przerwy) i prawdopodobnie zwiększyć wydajność we / wy, jeśli harmonogram ma większy wybór co dalej czytać z dysku. Z mojego doświadczenia wynika, że rozsądne stosowanie make -jprawie zawsze prowadzi do pewnej poprawy.
Flexo
1
@BrianKnoblauch Ale na mojej maszynie (prawdziwej lub w VirtualBox), jest ona związana z procesorem, zauważyłem, że procesor jest zajęty przez polecenie „top” podczas kompilacji.
大 宝剑
1
Nawet jeśli są one związane we / wy, możemy użyć flagi gcc '-pipe', aby zmniejszyć ból.
Twoja liczba -j powinna być 1,5 razy większa od liczby posiadanych rdzeni.
Mark Beckwith
2
Dzięki. Wciąż próbowałem przekazać „-j #” do gcc przez CFLAGS / CPPFLAGS / CXXFLAGS. Zupełnie zapomniałem, że "-j #" jest parametrem dla make GNU (a nie dla GCC).
chriv
33
Dlaczego opcja -j dla GNU Make musi być 1,5 razy większa od liczby rdzeni procesora?
bitek
28
Liczba 1.5 jest spowodowana zauważonym problemem związanym z we / wy . To praktyczna zasada. Około 1/3 zadań będzie czekała na operacje we / wy, więc pozostałe zadania będą wykorzystywać dostępne rdzenie. Liczba większa niż liczba rdzeni jest lepsza i możesz nawet osiągnąć nawet 2x . Zobacz także: Gnu -jargumentuje
bezartowy hałas
4
@JimMichaels Może tak być, ponieważ zależności są źle ustawione w projekcie (cel zaczyna budować, nawet jeśli jego zależności nie są jeszcze gotowe), tak że tylko kompilacja sekwencyjna kończy się sukcesem.
Antonio
42
Nie ma takiej flagi, a posiadanie jednej jest sprzeczne z filozofią Uniksa, zgodnie z którą każde narzędzie wykonuje tylko jedną funkcję i wykonuje ją dobrze. Tworzenie procesów kompilatora jest koncepcyjnie zadaniem systemu kompilacji. To, czego prawdopodobnie szukasz, to flaga -j (praca) do GNU make, a la
zrobić -j4
Lub możesz użyć pmake lub podobnych systemów do tworzenia równoległych.
„Unixowa pedanteria nie jest pomocna” Dobrze, że to nie była wtedy pedanteria, anonimowy redaktorze. Wycofana. Recenzenci powinni zwracać większą uwagę na to, co robisz.
Wyścigi lekkości na orbicie
12
Ludzie wspominali o podobnej koncepcji, makeale bjamteż ją popierają. Korzystanie z bjam -jxinstrukcji bjam do zbudowaniax współbieżnych poleceń.
Używamy tych samych skryptów kompilacji w systemach Windows i Linux, a użycie tej opcji skraca o połowę czas kompilacji na obu platformach. Miły.
+1 za -lmożliwość dodania wzmianki (nie rozpoczyna nowej pracy, chyba że wszystkie poprzednie prace zostały zakończone). W przeciwnym razie wydaje się, że zadanie konsolidatora nie rozpoczyna się od zbudowania wszystkich plików obiektowych (ponieważ niektóre kompilacje nadal trwają), więc zadanie konsolidatora kończy się niepowodzeniem.
NGI
8
Jeśli używasz make, problem z -j. Od man make:
-j [jobs],--jobs[=jobs]Specifies the number of jobs (commands) to run simultaneously.If there is more than one -j option, the last one is effective.If the -j option is given without an argument, make will not limit the
number of jobs that can run simultaneously.
A przede wszystkim, jeśli chcesz napisać skrypt lub zidentyfikować liczbę dostępnych rdzeni (w zależności od środowiska i jeśli pracujesz w wielu środowiskach, może to bardzo się zmienić), możesz użyć wszechobecnej funkcji Pythona cpu_count():
make -j $(python3 -c 'import multiprocessing as mp; print(int(mp.cpu_count() * 1.5))')
Jeśli pytasz, dlaczego 1.5w komentarzu powyżej zacytuję bezartowy szum użytkownika:
Liczba 1.5 jest spowodowana zauważonym problemem związanym z we / wy. To praktyczna zasada. Około 1/3 zadań będzie czekała na operacje we / wy, więc pozostałe zadania będą wykorzystywać dostępne rdzenie. Liczba większa niż liczba rdzeni jest lepsza i możesz nawet osiągnąć nawet 2x.
Większość użytkowników Linuksa prawdopodobnie będzie wolała krótszy: make -j`nproc` z nprocw GNU Coreutils.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Jeśli używasz dysku SSD, we / wy nie będzie tak dużym problemem. Aby rozwinąć powyższy komentarz Ciro, możesz to zrobić: make -j $(( $(nproc) + 1 ))(upewnij się, że wstawiłeś spacje tam, gdzie je mam).
Ed K
Fajna sugestia użycia Pythona, na systemach, gdzie nprocnie jest dostępny, np. W manylinux1kontenerach, oszczędza dodatkowy czas, unikając uruchamiania yum update/ yum install.
hafling
7
distcc może być również używane do dystrybucji kompilacji nie tylko na bieżącej maszynie, ale także na innych maszynach w farmie, na których zainstalowano distcc.
Nie jestem pewien co do g ++, ale jeśli używasz GNU Make to "make -j N" (gdzie N to liczba wątków, które może utworzyć) pozwoli make na uruchomienie wielu zadań g ++ w tym samym czasie (tak długo ponieważ pliki nie są od siebie zależne).
nie Nie ma liczby wątków! Wiele osób źle to rozumie, ale -j Nmówi, że należy uruchomić liczbę procesów naraz, a nie wątków. To jest powód, dla którego nie jest tak wydajny jak MS cl -MT(naprawdę wielowątkowy).
DO ZROBIENIA: Myślę, że gdzieś przeczytałem, że kompilację można zredukować do mnożenia macierzy, więc być może jest też możliwe przyspieszenie kompilacji pojedynczego pliku dla dużych plików. Ale nie mogę teraz znaleźć odniesienia.
make -j
prawie zawsze prowadzi do pewnej poprawy.Odpowiedzi:
Możesz to zrobić za pomocą make - za pomocą gnu make jest to flaga -j (pomoże to również na komputerze jednoprocesorowym).
Na przykład, jeśli chcesz, aby marka miała 4 równoległe zadania:
Możesz także uruchomić gcc w potoku z
Spowoduje to potokowanie etapów kompilacji, co również pomoże utrzymać zajęcie rdzeni.
Jeśli masz również dodatkowe maszyny, możesz sprawdzić distcc , który będzie kompilował również do nich.
źródło
-j
argumentujeNie ma takiej flagi, a posiadanie jednej jest sprzeczne z filozofią Uniksa, zgodnie z którą każde narzędzie wykonuje tylko jedną funkcję i wykonuje ją dobrze. Tworzenie procesów kompilatora jest koncepcyjnie zadaniem systemu kompilacji. To, czego prawdopodobnie szukasz, to flaga -j (praca) do GNU make, a la
Lub możesz użyć pmake lub podobnych systemów do tworzenia równoległych.
źródło
Ludzie wspominali o podobnej koncepcji,
make
alebjam
też ją popierają. Korzystanie zbjam -jx
instrukcji bjam do zbudowaniax
współbieżnych poleceń.Używamy tych samych skryptów kompilacji w systemach Windows i Linux, a użycie tej opcji skraca o połowę czas kompilacji na obu platformach. Miły.
źródło
make
zrobi to za Ciebie. Zbadaj przełączniki-j
i-l
na stronie podręcznika. Nie sądzę, abyg++
można go było równolegle.źródło
-l
możliwość dodania wzmianki (nie rozpoczyna nowej pracy, chyba że wszystkie poprzednie prace zostały zakończone). W przeciwnym razie wydaje się, że zadanie konsolidatora nie rozpoczyna się od zbudowania wszystkich plików obiektowych (ponieważ niektóre kompilacje nadal trwają), więc zadanie konsolidatora kończy się niepowodzeniem.Jeśli używasz make, problem z
-j
. Odman make
:A przede wszystkim, jeśli chcesz napisać skrypt lub zidentyfikować liczbę dostępnych rdzeni (w zależności od środowiska i jeśli pracujesz w wielu środowiskach, może to bardzo się zmienić), możesz użyć wszechobecnej funkcji Pythona
cpu_count()
:https://docs.python.org/3/library/multiprocessing.html#multiprocessing.cpu_count
Lubię to:
Jeśli pytasz, dlaczego
1.5
w komentarzu powyżej zacytuję bezartowy szum użytkownika:źródło
make -j`nproc`
znproc
w GNU Coreutils.make -j $(( $(nproc) + 1 ))
(upewnij się, że wstawiłeś spacje tam, gdzie je mam).nproc
nie jest dostępny, np. Wmanylinux1
kontenerach, oszczędza dodatkowy czas, unikając uruchamianiayum update
/yum install
.distcc może być również używane do dystrybucji kompilacji nie tylko na bieżącej maszynie, ale także na innych maszynach w farmie, na których zainstalowano distcc.
źródło
Nie jestem pewien co do g ++, ale jeśli używasz GNU Make to "make -j N" (gdzie N to liczba wątków, które może utworzyć) pozwoli make na uruchomienie wielu zadań g ++ w tym samym czasie (tak długo ponieważ pliki nie są od siebie zależne).
źródło
-j N
mówi, że należy uruchomić liczbę procesów naraz, a nie wątków. To jest powód, dla którego nie jest tak wydajny jak MScl -MT
(naprawdę wielowątkowy).Równolegle z GNU
Robiłem test porównawczy kompilacji syntetycznej i nie mogłem zawracać sobie głowy pisaniem pliku Makefile, więc użyłem:
Wyjaśnienie:
{.}
pobiera argument wejściowy i usuwa jego rozszerzenie-t
wypisuje wykonywane polecenia, aby dać nam wyobrażenie o postępie--will-cite
usuwa prośbę o cytowanie oprogramowania, jeśli publikujesz przy jego użyciu wyniki ...parallel
jest tak wygodny, że mógłbym sam sprawdzić datownik:xargs -P
może również uruchamiać zadania równolegle, ale nieco mniej wygodne jest manipulowanie rozszerzeniami lub uruchamianie z nim wielu poleceń: wielu poleceń Wywoływanie wielu poleceń przez xargsPoproszono o linkowanie równoległe pod adresem: Czy gcc może używać wielu rdzeni podczas łączenia?
DO ZROBIENIA: Myślę, że gdzieś przeczytałem, że kompilację można zredukować do mnożenia macierzy, więc być może jest też możliwe przyspieszenie kompilacji pojedynczego pliku dla dużych plików. Ale nie mogę teraz znaleźć odniesienia.
Testowane w Ubuntu 18.10.
źródło