Autor Wątek: Nie planowane przyspieszenie kodu  (Przeczytany 2804 razy)

Offline baca130

  • Użytkownik

# Sierpień 16, 2011, 17:53:14
Nieoczekiwane przyspieszenie kodu
Witam!
Mam takie dziwne pytanie:
Czy sposób zamieszczania headerów może przyśpieszyć kod?
Mianowicie piszę mały silnik 3d i wcześniej include zamieszczałem w jednej klasie "engine.h", ale to rozwiązanie było zbyt wolne ponieważ wymagało kompilacji całego silnika po najmniejszej zmianie w którymkolwiek z załączonych plików. Więc postanowiłem trochę uporządkować mój kod i tym razem w każdym pliku nagłówkowym załączam include z użytymi w nim klasami a w pliku źródłowym zamieszczam odnośnik do niego i ewentualnie inne wymagane nagłówki . Przez ten trochę żmudny zabieg kompiluje się o wiele szybciej, bez konieczności  kompilacji całego procesu.  Ale to nie koniec rewelacji,  nie wiem dlaczego  silnik nagle przyspieszył o ponad 40 procent?  Oczywiście bez żadnej ingerencji w klasach silnika.
Ktoś wie dlaczego?

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline sanyol

  • Użytkownik

# Sierpień 16, 2011, 18:05:52
a wdł mnie szkoda ze wyrzuciłes wszystkie includy z engine.h ponieważ istnieje coś takiego jak precompiled headers - na warsztacie jest na ten temat artykuł. Dzięki takiemu zabiegowi rekompilacja przyśpieszyła się mi 7'krotnie!

Co do samego przyśpieszenia silnika to pojęcia nie mam ;p

Offline counterClockWise

  • Użytkownik

# Sierpień 16, 2011, 18:08:01
nie wiem dlaczego  silnik nagle przyspieszył o ponad 40 procent?  Oczywiście bez żadnej ingerencji w klasach silnika.
Ktoś wie dlaczego?

1. Jak przyspieszył? Jak to zmierzyłeś i z jakiej wartości absolutnej na jaką? Może ta nieoczekiwana zmiana wynika z jakiegoś błędu pomiaru wydajności.

2. Dziwne. Jeżeli sama zmiana includowania miała taki wpływ, to wygląda na to, że popełniłeś jakiś gruby błąd projektowy w swoim silniku.

3. Myślę, że Ty najbardziej jesteś w stanie powiedzieć co spowodowało zmianę. Proponuję stopniowo, po jednym include wracać do poprzedniej sytuacji i sprawdzać czy silnik zwolni. W ten sposób możesz skupić uwagę w którym miejscu siedzi zmiana.

PS Poprawnie jest "nieplanowane".
« Ostatnia zmiana: Sierpień 16, 2011, 18:10:33 wysłana przez counterClockWise »

Offline baca130

  • Użytkownik

# Sierpień 16, 2011, 18:36:10
@up fps counterem. z 450 na 760
a wracać do poprzedniego stanu nie zamierzam, zbyt dużo bawienia.
jak błąd to jak go poprawiłem nie ingerując w kod? jedynie zniana miejsc include co według mnie nie powinno przyśpieszyć.
@up2 silnik też jest pisany pod Androida, a tam nie wiem jak to się robi.

Offline ShadowDancer

  • Redaktor

# Sierpień 16, 2011, 18:37:31
sanyol: Precompiled headers używa się raczej dla rzeczy, które są już gotowe(np stl), bo je też trzeba przekompilować.

Offline nembutal

  • Użytkownik

# Sierpień 16, 2011, 19:51:19
@up fps counterem. z 450 na 760
Z ilu milisekund na ile?

Czy przypadkiem zmiany nie skutkowały tym, że większa liczba plików źródłowych trafiła do jednego pliku object? Kompilator ma wtedy większe pole do optymalizacji (chociaż bez szaleństw).
« Ostatnia zmiana: Sierpień 16, 2011, 19:53:16 wysłana przez nembutal »

Offline Xirdus

  • Redaktor

# Sierpień 16, 2011, 19:59:31
Z ilu milisekund na ile?
Tak trudno policzyć? Z 2,2ms na 1,3ms. Według mnie taka zmiana jest całkowicie przypadkowa - chyba, że robiłeś testy godzinami, a nową wersję odpaliłeś zaraz po starej. Tak czy inaczej, nie przejmuj siętą zmianą. A w poszczególnych nagłówkach includuj jak najmniej - tylko must-have. Jeśli w pliku A.cpp używasz funkcji z B.h, to include'a dajesz nie w A.h, tylko w A.cpp.

Offline Kos

  • Użytkownik
    • kos.gd

# Sierpień 16, 2011, 20:03:36
Może w jednym przypadku kompilator mógł inlinować więcej funkcji, dlatego działa szybciej.

Offline vinc999

  • Użytkownik

# Sierpień 16, 2011, 20:06:29
Tak trudno policzyć? Z 2,2ms na 1,3ms. Według mnie taka zmiana jest całkowicie przypadkowa - chyba, że robiłeś testy godzinami, a nową wersję odpaliłeś zaraz po starej. Tak czy inaczej, nie przejmuj siętą zmianą. A w poszczególnych nagłówkach includuj jak najmniej - tylko must-have. Jeśli w pliku A.cpp używasz funkcji z B.h, to include'a dajesz nie w A.h, tylko w A.cpp.

Wlacze sie ze swoimi pytaniami:)

A dlaczego tak includowac?? Pytanie z ciekawosci

Z reszta, ja do tej pory robilem tak, ze robilem sobie jeden plik, gdzie po kolei byly dodawane rozne pliki, a oprocz tego w kazdym pliku wpisywalem includy do bibliotek, ktorych on uzywa. No a wszystko umieszczalem w konstrukcjach:

#ifndef costam
#def costam
(...kod...)
#endif

Zle robie?

Offline Xirdus

  • Redaktor

# Sierpień 16, 2011, 20:15:05
A dlaczego tak includowac?? Pytanie z ciekawosci
Załóżmy, że plik A.cpp używa funkcji z pliku B.h, a klasa C ma składową typu A. Plik C.h musi includować A.h - nie ma bata (chyba że zamiast składowej klasy użyjesz wskaźnika lub referencji). Jednak gdy plik A.h będzie includował plik B.h, to będzie on także automatycznie dołączany do kodu klasy C - mimo, że będzie całkowicie zbędny, i tak trzeba będzie go skompilować.

Z reszta, ja do tej pory robilem tak, ze robilem sobie jeden plik, gdzie po kolei byly dodawane rozne pliki, a oprocz tego w kazdym pliku wpisywalem includy do bibliotek, ktorych on uzywa. No a wszystko umieszczalem w konstrukcjach (...) Zle robie?
Im mniej nagłówków każdy plik includuje tym szybsza jest kompilacja. Dodatkowo możesz użyć precompiled headers - poczytaj sobie o tym.

Offline vinc999

  • Użytkownik

# Sierpień 16, 2011, 20:28:33
OK, ale jak rozumiem (tak czy tak doczytam), ale tak czy tak pliki, ktore pisze sa potrzebne (jakby nie byly to po co bym mial je pisac) i gdzies je dolacze. Tak czy tak taka biblioteka jest tylko raz dolaczana, a kolejne razy sa ignorowane przez preprocesor.

No a jak skoncze jakis modul, ktory jest niezalezny od reszty programu to moge sobie go prekompilowac. Nie tak to dziala?

Offline sanyol

  • Użytkownik

# Sierpień 16, 2011, 20:41:28
Cytuj
sanyol: Precompiled headers używa się raczej dla rzeczy, które są już gotowe(np stl), bo je też trzeba przekompilować.

Trzeba trzeba, ale kompilacja odbywa sie naprawde mega szybko i nie chodzi mi o modyfikacje plików nagłówkowych tylko o pisanie np. w .cpp, dzieki precompiled headers kompilacja tego trwa naprawde kilka sekund - a wlasnie w source zazwyczaj sie cos zmienia . Nie ma co duzo pisać, musiał bys sam zobaczyć jak to ułatwia życie. Jak masz poinkludowanego wszedzie windowsa, ogla , stla itp to naprawde czuc roznice po przejsciu na precompiled headers.

Offline Xirdus

  • Redaktor

# Sierpień 16, 2011, 21:20:02
OK, ale jak rozumiem (tak czy tak doczytam), ale tak czy tak pliki, ktore pisze sa potrzebne (jakby nie byly to po co bym mial je pisac) i gdzies je dolacze.
W obrębie jednej jednostki kompilacji - masz rację. Ale pamiętaj, że każdy plik .cpp jest kompilowany osobno, i dopiero na końcu są one łączone. Kompilator jest odpalany od nowa dla każdej jednostki kompilacji - dane o definicjach klas, deklaracjach funkcji, makrach preprocesora są tracone i każdy dołączany plik .h jest parsowany na nowo.

Offline baca130

  • Użytkownik

# Sierpień 16, 2011, 21:27:45
To wszystkie src daj w inklude do jednego pliku i wyklucz z kompilacji, wtedy będziesz miał tylko jedne użycie kompilatora. :) // ort
« Ostatnia zmiana: Sierpień 18, 2011, 05:53:47 wysłana przez Dab »

Offline vinc999

  • Użytkownik

# Sierpień 16, 2011, 21:29:16
Troche mi to rozjasnia.

Pewnie jakbym napisal cos wiekszego i mial potrzebe dzielenia tych plikow na h i cpp to zapewne bym zauwazyl taka potrzebe.

Choc nie powiem, kiedys chyba doswiadczylem kompilacji dlugiego kodu - jak bawilem sie w MFC, no i tam czas kompilacji mnie troche wnerwial.