Jak przyspieszyć czas kompilacji g++ (przy użyciu wielu szablonów)

To pytanie jest może jakoś dziwne, ale jak mogę przyspieszyć czas kompilacji g++? Mój kod C++ mocno wykorzystuje boost i szablony. Już przeniosłem jak najwięcej z plików nagłówków i użyłem opcji-j, ale i tak kompilacja (i link) zajmuje sporo czasu.

Czy są jakieś narzędzia, które analizują mój kod i wskazują na potrzeby kompilatora? Czy można w jakiś sposób profilować kompilator działający na moim kodzie? To byłoby naprawdę miłe, bo czasami mam wrażenie, że za dużo czasu spędziłem wpatrując się w Log konsoli kompilatora ...

Author: Danvil, 2010-08-03

11 answers

Co było dla mnie najbardziej przydatne:

  • Zbuduj na systemie plików RAM. To jest trywialne na Linuksie. Możesz zachować kopię wspólnych plików nagłówkowych (wstępnie skompilowanych lub rzeczywistych .plików h) także na systemie plików RAM.
  • wstępnie skompilowane nagłówki . Mam jedną na (główną) bibliotekę (np. Boost, Qt, stdlib).
  • Declare zamiast include classes where possible. Zmniejsza to zależności, a tym samym liczbę plików, które muszą zostać skompilowane po zmianie plik nagłówkowy.
  • paralelize make . Zazwyczaj pomaga to w każdym przypadku, ale mam -j3 globalnie dla make. Upewnij się jednak, że wykresy zależności są poprawne w pliku Makefile, w przeciwnym razie możesz mieć problemy.
  • Użyj -O0, jeśli nie testujesz szybkości wykonania lub rozmiaru kodu (a Twój komputer jest na tyle szybki, że nie zależy Ci zbytnio na (prawdopodobnie małej) wydajności).
  • Kompiluj za każdym razem, gdy zapisujesz. Niektórym się to nie podoba, ale pozwala na błędy można wyświetlać wcześnie i można je wykonywać w tle, co skraca czas oczekiwania na pisanie i przygotowanie do testów.
 46
Author: strager,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-03 14:20:47

Oto co zrobiłem, aby przyspieszyć Kompilacje w bardzo podobnym scenariuszu, który opisujesz (boost, templates, gcc)

  • budowanie na dysku lokalnym zamiast sieciowego systemu plików, takiego jak NFS
  • upgrade do nowszej wersji gcc
  • zbadaj distcc
  • szybsze budowanie systemów, szczególnie więcej pamięci RAM
 17
Author: Sam Miller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-03 13:55:32

Zakładam, że mówimy o minutach do skompilowania pliku, tzn. wstępnie skompilowane nagłówki lub problemy z lokalnym dyskiem nie są problemem.

Długie czasy kompilacji z głębokim kodem szablonu (boost itp.) jest często zakorzeniony w nieprzyjaznym asymptotycznym zachowaniu gcc, jeśli chodzi o instancję szablonu, w szczególności gdy różne szablony są emulowane z domyślnymi argumentami szablonu.

Oto dokument, który nazywa skrócony czas kompilacji jako motywację do różnych szablony:

Cpptruths miał artykuł o tym, jak gcc-4.5 jest znacznie lepszy w tym zakresie i jak radzi sobie znakomicie ze swoimi zmiennymi szablonami:

IIRC wtedy BOOST ma sposób na ograniczenie generowania domyślnych parametrów szablonu dla pseudo-variadics, myślę ,że ' g++ -DBOOST_MPL_LIMIT_LIST_SIZE = 10 ' powinno działać (domyślnie 20)

UPDATE: jest też fajny wątek z ogólnymi technikami przyspieszającymi kompilację, więc może się przydać:

UPDATE: ten jest o problemach z wydajnością przy kompilowaniu szablonów, akceptowana odpowiedź również zaleca gcc-4.5, również clang jest wymieniony jako pozytywny przykład:

 17
Author: Nordic Mainframe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:33

Jeśli robisz dużo rekompilacji, ccache może pomóc. To nie przyspiesza kompilacji, ale da ci wynik buforowany, jeśli zdarzy ci się zrobić bezużyteczną rekompilację z jakiegoś powodu. Może to sprawiać wrażenie rozwiązania niewłaściwego problemu, ale czasami reguły przebudowy są tak skomplikowane, że w rzeczywistości kończy się to tym samym krokiem kompilacji podczas nowej kompilacji.

Dodatkowy pomysł: jeśli twój kod kompiluje się z clang , Użyj go zamiast tego. Zwykle jest szybszy niż gcc.

 9
Author: viraptor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-10 11:25:53

Oprócz tego, co inni dodali i co już robisz (równoległa Budowa, opcje kompilatora itp.), rozważ ukrywanie szablonów w klasach implementacyjnych, dostępnych za pośrednictwem interfejsów. Oznacza to, że zamiast mieć klasę taką jak:

// ClsWithNoTemplates.h file, included everywhere

class ClsWithTemplates
{
    ComplicatedTemplate<abc> member;
    // ...

public:
    void FunctionUsingYourMember();
};

Powinieneś mieć:

// ClsWithNoTemplates.h file:

class ClsWithTemplatesImplementation; // forward declaration
  // definition included in the ClsWithNoTemplates.cpp file
  // this class will have a ComplicatedTemplate<abc> member, but it is only 
  // included in your ClsWithNoTemplates definition file (that is only included once)


class ClsWithNoTemplates
{
     ClsWithTemplatesImplementation * impl; // no templates mentioned anywhere here
public:
    void FunctionUsingYourMember(); // call impl->FunctionUsingYourMember() internally
};

To trochę zmienia Twój projekt OOP, ale jest to dla dobra: włączenie definicji 'ClsWithNoTemplates' jest teraz szybkie i dopiero (pre)kompilujesz definicję 'ClsWithNoTemplates' raz.

Dodatkowo, jeśli zmienisz kod implementacji, każdy kod, który zawierał ClsWithNoTemplates.h prawdopodobnie nie będzie musiał być redefiniowany.

Ta zmiana powinna znacznie wydłużyć czas częściowej kompilacji, a pomoże również w przypadku, gdy Twój ClsWithNoTemplates jest publicznym interfejsem wyeksportowanym z pliku biblioteki: ponieważ plik nie jest zmieniany, gdy tylko zmienisz implementację, Twój zależny kod klienta nie musi być w ogóle rekompilowany.

 3
Author: utnapistim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-03 15:41:50

Spróbuj techniki PIMPL, to pytanie: jakich technik można użyć, aby przyspieszyć czas kompilacji C++?

Uniemożliwi kompilatorowi śledzenie łańcucha plików nagłówkowych i implementacji za każdym razem, gdy będziesz musiał coś zrobić.

 3
Author: gtrak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:17:58

Jeśli jest dużo plików, możesz przyspieszyć kompilację, mając tylko jeden .plik cpp, który #zawiera wszystkie inne .pliki cpp. To oczywiście wymaga, aby być bardziej ostrożnym z makrami i takie, że już zdefiniowane na plik, ponieważ będą one teraz widoczne dla innych plików cpp.

Jeśli jest wiele plików, może to znacznie skrócić czas kompilacji.

 2
Author: Zitrax,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-03 14:25:15

Tworzy instancje mniej szablonów i funkcji wbudowanych. Prekompiluj tyle, ile możesz i po prostu połącz, a nie Kompiluj wszystko od zera. Upewnij się, że używasz najnowszej wersji GCC.

Jest jednak prostym faktem, że C++ jest niezwykle złożonym językiem, a jego kompilowanie zajmuje sporo czasu.

 1
Author: Puppy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-03 13:34:52

Ten artykuł opisuje metodę kompilacji kodu szablonu, podobnie jak "tradycyjne" pliki obiektowe niebędące szablonem. Oszczędza czas kompilacji i łącza, z tylko jedną linią kodu na instancję szablonu.

 1
Author: Chris Tonkinson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-04 12:02:41

Zwykle najdroższymi częściami kompilacji są (a) odczyt plików źródłowych (wszystkie) oraz (b) wczytywanie kompilatora do pamięci dla każdego pliku źródłowego.

Jeśli masz 52 pliki źródłowe (. cc), z których każdy # zawiera 47 # include (.h) pliki, wczytasz kompilator 52 razy, a będziesz przeglądał 2496 plików. W zależności od gęstości komentarzy w plikach możesz spędzać sporo czasu na jedzeniu bezużytecznych postaci. (W jednym organizacja widziałem, pliki nagłówkowe wahały się od 66% do 90% komentarzy, przy czym tylko 10% -33% pliku jest "znaczące". Najlepszą rzeczą, jaką można było zrobić, aby poprawić czytelność tych plików, było usunięcie każdego ostatniego komentarza, pozostawiając tylko kod.)

Przyjrzyj się, jak Twój program jest fizycznie zorganizowany. Sprawdź, czy możesz łączyć pliki źródłowe i uprościć hierarchię plików # include.

Dekady temu firmy takie jak IBM to rozumiały i pisały ich Kompilatory, aby kompilator mógł otrzymać listę plików do skompilowania, a nie tylko jeden plik, a kompilator byłby ładowany tylko raz.

 0
Author: John R. Strohm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-03 13:48:25

Kompilowanie z g++ przy użyciu wielu rdzeni

Kompilowanie z g++ przy użyciu wielu rdzeni

 0
Author: karlphillip,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:53