2010-12-14 10 views
10

Czy ktoś mógłby mi podać wskazówki, jak zwiększyć prędkość budynku w studiu visual 2008?
Mam duży projekt z wieloma modułami z pełnym źródłem. Za każdym razem, gdy jest tworzony, wszystkie pliki są przebudowywane, niektóre z nich nie zostały zmienione. Czy mogę zapobiec odbudowaniu tych plików? Odwróciłem się własnością „Włącz Minimalna odbudować”/GM na ale kompilator wyrzucił to ostrzeżenieJak zoptymalizować prędkość budynku w visual studio 2008

Command line warning D9030 : '/Gm' is incompatible with multiprocessing; ignoring /MP switch 

Co wskazówki, aby zwiększyć szybkość budowania pomoże mi dużo. Dziękujemy,

+0

Mówisz, że - buduj wszystko, niczego nie zmieniaj, a wszystko jeszcze raz skompilujesz? –

+0

Xoreax Incredibuild, choć nie tanie, bardzo pomaga. Regularnie otrzymujemy przyspieszenia> 10x. To powiedziawszy, zerwane zależności nadal bardzo boli, ponieważ wymusza kosztowne ponowne łączenie. – MSalters

Odpowiedz

2

Prostym sposobem jest kompilacji w trybie debugowania (aka zerowe optymalizacji), to oczywiście jest tylko do testów wewnętrznych.

można również użyć prekompilowanych nagłówków *, aby przyspieszyć przetwarzanie lub oderwać "niezmienne" segmenty w statyczne biblioteki, usuwając je z rekompilacji.

* z /MP trzeba stworzyć prekompilowanego nagłówek przed wykonaniem wieloprocesowej kompilację, jak /MP może czytać ale nie pisać zgodnie z MSDN

+0

Z mojego doświadczenia wynika, że ​​kompilowanie w trybie debugowania jest znacznie wolniejsze, ponieważ zapis informacji debugowania powoduje znacznie więcej aktywności na dysku. – fschmitt

+1

@fschmitt: wiesz, że możesz kompilować w trybie debugowania i nie generować tych informacji, ich (prawie) to samo, co kompilowanie w wersji bez optymalizacji, w żaden sposób osiąga to, co miałem na myśli, usuwając kosztowny czas optymalizacji, i nie działa nie czyni żadnych innych punktów mniej prawdą ... – Necrolis

2

Czy możesz podać więcej informacji na temat struktury projektu i plików, które są przebudowywane?
niezmienione pliki C++ może zostać przebudowany, ponieważ zawierają one nagłówku plików, które zostały zmienione, w tym przypadku/option Gm nie pomoże

+0

Nasz projekt ma kilka zewnętrznych projektów open source. – tiboo

6

Enable Minimal Build: /Gm jest niezgodna z Build with Multiple Processes: /MP{<cores>}
W ten sposób można używać tylko jednego z tych dwóch naraz.

/g> Właściwości projektu: Właściwości konfiguracji>C/C++>CodeGeneration
lub
/MP {A}> Właściwości projektu: Właściwości konfiguracji>C/C++ >Linia poleceń


Aby zapobiec niepotrzebnym kompilacjom (nietkniętym plikom) - odpowiednio skonstruuj kod ; Przestrzegać tej reguły:

W [.h] pliki nagłówka, umieść tylko to, co jest potrzebne przez zawartość samego pliku nagłówka;
i wszystko, czego potrzebujesz do współużytkowania w wielu jednostkach wykonawczych.

Reszta idzie w realizacji [.c/.cpp] plików.

+0

OK, ale które z 2 należy preferować? Jeśli wykluczają się wzajemnie, dlaczego Microsoft nie zachował najlepszego? –

2

Przebudowywanie wszystkich plików po zmianie jednego pliku nagłówkowego jest częstym problemem.Rozwiązaniem jest dokładne sprawdzenie, co #include użyć plików nagłówkowych i usunąć wszystko, co można usunąć. Jeśli tylko Twój kod wykorzystuje wskaźniki i referencje do klasy, można zastąpić

#include "foo.h" 

z

class Foo; 
16

C++ skompilować czasy bitwy dla każdego projektu powyżej pewnej wielkości. Na szczęście, przy tak dużej liczbie osób piszących duże projekty w C++, istnieje wiele różnych rozwiązań:

Klasycznym, tanim rozwiązaniem jest "budowanie jedności". Oznacza to po prostu użycie #include, aby umieścić wszystkie pliki .cpp w jednym pliku do kompilacji. "Unity build" pojawił się w wielu pytaniach tutaj na stackoverflow, here jest najbardziej znanym, o którym wiem. Ten screencast pokazuje, jak skonfigurować taką kompilację w Visual Studio.

Rozumiem, że kompilacje jedności są znacznie szybsze niż klasyczne, ponieważ skutecznie buforują pracę wykonaną przez preprocesor i łącznik. Jedną wadą kompilacji jedności jest to, że jeśli dotkniesz jednego pliku cpp, przekompilujesz "duży" plik cpp. Możesz obejść ten problem, przełamując plik cpp, który jest iterowany, z kompilacji jedności i kompilując ją samodzielnie.

Beyond Jedność buduje, oto lista moich najlepszych praktyk:

  • Zastosowanie #include tylko gdy neccessary, wolą przodu deklaracji
  • Użyj pimpl idiom utrzymać realizację klasy z powszechnie włączonych plików nagłówkowych. Dzięki temu można dodawać elementy do implementacji bez ponownej rekompilacji
  • Używać prekompilowanych nagłówków (pch) dla często dołączanych plików nagłówkowych, które rzadko zmieniają się
  • Upewnij się, że twój system kompilacji używa wszystkich dostępnych rdzeni na lokalnym sprzęcie
  • przechowywać listę katalogów preprocesor musi szukać minimal, użyj precyzyjnych ścieżek w #include sprawozdania
  • Korzystając #pragma once na górze plików nagłówkowych zamiast #ifndef __FOO_H #define __FOO_H ... #endif, jeśli używasz #ifndef lewę kompilator będzie mieć aby otworzyć plik nagłówkowy za każdym razem, gdy jest włączony, #pragma once al obniża kompilator, aby być bardziej wydajnym

Jeśli robisz to wszystko (budowanie jedności zrobi największą różnicę, z mojego doświadczenia), ostatnią opcją jest rozproszony budynek. distcc to najlepsze darmowe rozwiązanie, o którym wiem, że jest to zastrzeżony standard branżowy. Jestem zdania, że ​​przetwarzanie rozproszone będzie jedynym sposobem na uzyskanie doskonałych czasów iteracji z nieuporządkowanego procesu kompilacji C++. Jeśli masz dostęp do dość dużej liczby maszyn (powiedzmy 10-20), to jest to całkowicie warte zainteresowania. Powinienem wspomnieć, że budowanie jedności i rozproszone kompilacje nie są całkowicie symbiotyczne, ponieważ tradycyjna kompilacja może zostać podzielona na mniejsze części pracy niż kompilacja jedności. Jeśli chcesz je rozpowszechniać, prawdopodobnie nie warto konfigurować jedności.

+1

Dla porządku #pragma raz i zawiera strażnika, zauważyłem, że (1) Microsoft umieścił #pragma po włączeniu strażnika (2) Nawet #pragma przychodzi po zabezpieczeniu włączającym, kompilator może również pominąć otwieranie pliku. Mój test oparty na VC2010 + SP1, używam/showincludes i procmon do zbadania tego problemu. – zhaorufei