Autor Wątek: STL, usuwanie bieżącego elementu w pętli  (Przeczytany 5508 razy)

Offline yarpen

  • Użytkownik

# Październik 23, 2009, 15:39:22
Yarpen: co to znaczy, że się słabo skaluje?
To moja nowomowa. Chodzi o to, ze rozszerzenie warunkow zazwyczaj nie jest trywialne. Zalozmy, ze za jakis czas designer przychodzi i chce zeby usuwac obiekty, ktore sa martwe, no i dodatkowo nie maja many (przyklad z czapy, ale chodzi o ilustracje). W wersji 'oldschoolowej' dodajemy jedno &&. W wersji z erase-remove bedzie troche gimnastyki.

Offline Mr. Spam

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

Offline bies

  • Użytkownik

# Październik 23, 2009, 19:58:00
Yarpen: co to znaczy, że się słabo skaluje?
To moja nowomowa. Chodzi o to, ze rozszerzenie warunkow zazwyczaj nie jest trywialne. Zalozmy, ze za jakis czas designer przychodzi i chce zeby usuwac obiekty, ktore sa martwe, no i dodatkowo nie maja many (przyklad z czapy, ale chodzi o ilustracje). W wersji 'oldschoolowej' dodajemy jedno &&. W wersji z erase-remove bedzie troche gimnastyki.
Przychodzą mi do głowy dwie odpowiedzi. Pierwsza, że w rozwiązaniu z lambdą też będzie tylko jeden &&. Druga jest nieco inna. Spędziłem dziś trochę czasu audytując kod jednego z moich programistów. Nie było to C++ ale to nieistotne. Otóż, zaraz zapala mi się lampka z pytaniem kto ma decydować co należy usuwać. Kiedy to będzie jeszcze zmieniane. I czy, być może, nie warto tej decyzji wyodrębnić. Bo przyjdzie designer za jakiś czas i powie, że tak w ogóle to mana może być i mniejsza od zera i chciałby te obiekty wcześniej zobaczyć w zupełnie innej funkcji.

Offline Esidar

  • Użytkownik

# Październik 23, 2009, 21:00:39
Bo przyjdzie designer za jakiś czas i powie, że tak w ogóle to mana może być i mniejsza od zera i chciałby te obiekty wcześniej zobaczyć w zupełnie innej funkcji.
I tak zazwyczaj jest :) Niedoświadczony programista, albo ten który nie ma dużo czasu, robi pętlę na 1 linijkę za pomocą STL/Boost i/lub Lambda. Potem przychodzi designer, więc programista już lekko zirytowany rozbudowuje 1 linijkę do znacznie dłuższej lub rozbudowuje kod do dwóch linijek :) Ew. przyprawia to komentarzem "//HACK HACK temporary E3 Demo".
Za 3 lub 4 razem gdy designer przychodzi, programista wywala tą linijkę kodu i pisze system uniwersalny i bardziej rozbudowany, po czym stwierdza że mechanizmy z STL/Boost i/lub Lambda są mu w tej chwili na wafla i albo ma jaja i wywala cały Boost albo ma zapędy masochistyczne i pozostawia bibliotekę wydłużającą czas kompilacji o 400% ale liczy na to że "może się jeszcze przyda".


Jak już wszyscy lecą po OT, to ja też :) Ostatnio z ciekawości kompilowałem silnik Ogre który używa STL. Buildowało się to ustrojstwo potwornie długo, a potem się jeszcze okazało że różne pliki źródłowe które mają 20kB, generują .obj o wielkości 30MB. W środku takich plików potem można znaleźć np. takie nazwy:

??$_Debug_pointer@V?$_Vector_const_iterator@VVector3@Ogre@@V?$allocator@VVector3@Ogre@@@std@@@std@@@std@@YAXAAV?$_Vector_const_iterator@VVector3@Ogre@@V?$allocator@VVector3@Ogre@@@std@@@0@PB_WI@Z ??_EMovableObject@Ogre@@W3AEPAXI@Z

Cały renderer (bo tym jest właściwie Ogre) generuje 1,8GB plików .obj i kompiluje się dłużej niż całkiem spora, rozbudowana i skończona gra AAA która oprócz krótszego czasu kompilacji, generuje tylko 300MB .obj i o połowę krótszy .exe/dll.

Jak widać można pisać kod oraz KOD :) Jeżeli ktoś chce zaoszczędzić kilka sekund na pisaniu 1 linijki kodu. Proszę bardzo :) Ja wolę poświęcić na to 2x więcej sekund i zaoszczędzić potem kilkaset osobogodzin na kompilacji. No cóż. Jestem niecierpliwy i lubię jak mi się szybko kompiluje :)
« Ostatnia zmiana: Październik 23, 2009, 21:05:42 wysłana przez Esidar »

Offline bies

  • Użytkownik

# Październik 23, 2009, 21:52:14
OGRE? Tj. ogre3d.org? Wersja 1.6.4 może?

Aż sprawdziłem. U mnie, na domowej stacji roboczej (energooszczędny Phenom 9150e, żaden buildserwer) buduję się (z dobrą optymalizacją) 4 minuty. Wszystkie pliki o zajmują 19MiB. Nic nie mówię o kompilatorach, nic a nic...

// edit
Żeby było jasne, sam renderer -- bez przykładów.

// edit^2
Sprawdziłem wersję z optymalizacją i pełnymi informacjami dla debuggera: czas kompilacji 3 min. 4 sek. (cache dyskowy, tak przy okazji dwa dyski SATA II spięte w RAID-0 -- więc powiedzmy, że dyski mam ok). Rozmiar plików o: 221 MiB.
« Ostatnia zmiana: Październik 23, 2009, 22:13:12 wysłana przez bies »

Offline Esidar

  • Użytkownik

# Październik 23, 2009, 23:18:34
buduję się (z dobrą optymalizacją) 4 minuty
No to u mnie na MSVC podobnie (bez RAID), prawie 5min. Nie mniej, to tylko renderer. Jakieś 5% gry którą przytoczyłem. W tej grze, sam lib z rendererem się kompiluje poniżej 1min.
U ciebie ogre się kompiluje 4min a to jest ile... 200 plików .cpp ? (samego ogre, nie wiem czy liczysz np. freetype). Gra o której mówię ma 3500 plików .cpp a kompiluje się 15min. Przelicz to na "jednostki ogrowe" (stosunek ilości plików do czasu kompilacji) :)
Pewnie w GCC by to poszło trochę szybciej... nie zamierzam się spierać... ale wolałbym nie kompilować tych 3500 plików, nawet w gcc, gdyby ta gra była napisana w stylu KOD zamiast kod.
« Ostatnia zmiana: Październik 23, 2009, 23:20:06 wysłana przez Esidar »

Offline ConayR

  • Użytkownik

# Październik 23, 2009, 23:31:59

Offline Esidar

  • Użytkownik

# Październik 23, 2009, 23:55:54
...
No coś w tym stylu :) Zdarzało mi się już podobnie :) Ostatnio niestety znowu. Jako ciekawostka kompiluję kod pod PS3 za pomocą gcc. Ale nie ma magii, czy gcc, czy msvc, tak samo się ciągnie jak krew z nosa.


Offline bies

  • Użytkownik

# Październik 23, 2009, 23:56:54
Bez przesady... Są prekompilowane nagłówki, jest ccache, są buildy przyrostowe, są też wreszcie odpowiednie maszyny. Jeśli moja praca polegałaby na częstym budowaniu 3500 jednostek translacji C++ to zapewnię sobie, że będą się budowały bardzo szybko. Do licha, nie będę upośledzał języka tylko dlatego, że nie mam odpowiednio skonstruowanego buildsystemu na odpowiednio wydajnym buildserwerze.

Mówię bardzo poważnie, jeśli trzeba to kupuje się 16 wydajnych rdzeni z 16 GiB RAM na których robi się ramdysk. Tylko, że normalna praca programisty (nie buildserwera który buduje wszystko od zera przy każdym żądaniu) to budowanie przyrostowe. A budowanie przyrostowe w dobrze zarządzanym projekcie C++ to kwestia kilku sekund.

Offline yarpen

  • Użytkownik

# Październik 24, 2009, 01:05:26
Mówię bardzo poważnie, jeśli trzeba to kupuje się 16 wydajnych rdzeni z 16 GiB RAM na których robi się ramdysk. Tylko, że normalna praca programisty (nie buildserwera który buduje wszystko od zera przy każdym żądaniu) to budowanie przyrostowe. A budowanie przyrostowe w dobrze zarządzanym projekcie C++ to kwestia kilku sekund.
Teraz to juz fantazjujesz. Samo linkowanie wiekszego projektu zajmie kilkanascie-kilkadziesiat (na moim sprzecie, ktory ma wlasnie 16GB RAMu).

Offline ConayR

  • Użytkownik

# Październik 24, 2009, 02:41:34
@bies: ale jesteś świadom tego, że czasem (często) trzeba zbudować coś na devboksie a nie na build maszynie i nikt nie kupi każdemu w firmie ośmiordzeniowego potwora z macierzą dysków do prywatnych buildów. A kolejkowanie zadań ludzi na build maszynach to bzdura, szczególnie że z definicji buduje się swój (zmieniony) kod, czyli najpierw to trzeba zacommitować gdzieś. W poprzedniej firmie w której pracowałem powstawały rozwiązania rozwiązujące ten problem (bezdyskowa chmura budująca non-stop), ale są one póki co w fazie koncepcyjnej.

Offline bies

  • Użytkownik

# Październik 24, 2009, 14:32:29
Mówię bardzo poważnie, jeśli trzeba to kupuje się 16 wydajnych rdzeni z 16 GiB RAM na których robi się ramdysk. Tylko, że normalna praca programisty (nie buildserwera który buduje wszystko od zera przy każdym żądaniu) to budowanie przyrostowe. A budowanie przyrostowe w dobrze zarządzanym projekcie C++ to kwestia kilku sekund.
Teraz to juz fantazjujesz. Samo linkowanie wiekszego projektu zajmie kilkanascie-kilkadziesiat (na moim sprzecie, ktory ma wlasnie 16GB RAMu).
Nie. Linkowanie + libtool biblioteki libOgreMain-1.6.4.so (58 MiB z informacjami dla debuggera) klasycznym ld trwa u mnie niecałe 4 sek. Używając gold (zoptymalizowane ld dla formatu ELF, napisane w C++ przez Google) poniżej 3 sek. Z czego większość to libtool, samo linkowanie to 1,2 sek. To jest duża binarka. Nawet jak masz większą (tj. projekt niepodzielony na biblioteki dynamiczne) to i tak powinieneś zmieścić się poniżej 10 sek. Niech zatem będzie, że przy bardzo dużych binarkach budowanie przyrostowe na normalnej maszynie to kilkanaście sekund. Mój normalny stan to właśnie kilka sekund (staram się nie mieć dużych binarek). W gruncie rzeczy nie ma znaczenia.

@bies: ale jesteś świadom tego, że czasem (często) trzeba zbudować coś na devboksie a nie na build maszynie i nikt nie kupi każdemu w firmie ośmiordzeniowego potwora z macierzą dysków do prywatnych buildów. A kolejkowanie zadań ludzi na build maszynach to bzdura, szczególnie że z definicji buduje się swój (zmieniony) kod, czyli najpierw to trzeba zacommitować gdzieś. W poprzedniej firmie w której pracowałem powstawały rozwiązania rozwiązujące ten problem (bezdyskowa chmura budująca non-stop), ale są one póki co w fazie koncepcyjnej.
Zdaję sobie sprawę (ba, zazwyczaj buduje się na stacjach roboczych). Dlatego piszę o budowaniu przyrostowym. A co do tego co jest w fazie koncepcyjnej: systemy budujące online widziałem już dobre parę lat temu. Distcc jeszcze wcześniej. A koncepcja jest starsza ode mnie. Z tym, że takie rozważania nie mają sensu bo normalna praca nie polega na make clean && make wykonywanym co 3 minuty.

Słuchajcie, ja naprawdę nie mam zamiaru nikogo przekonywać do używania Boosta, STL, TR1 itp. Ale argument o czasie budowania jest po prostu miękki.

Offline yarpen

  • Użytkownik

# Październik 24, 2009, 15:05:58
Słuchajcie, ja naprawdę nie mam zamiaru nikogo przekonywać do używania Boosta, STL, TR1 itp. Ale argument o czasie budowania jest po prostu miękki.
Ja tez akurat (wyjatkowo) nie o Boost czy STL, po prostu niezaleznie od wszystkiego - linkowanie duzych projektow troche trwa. Dodatkowo, czesto nie ma sie swobody wyboru najlepszego kompilatora. Na PS3 masz 2 opcje: SNC (wolny) albo GCC (wolniejszy) :)

Offline Aithne

  • Użytkownik

# Październik 24, 2009, 15:45:03
Czy na jakąkolwiek architekturę istnieje szybki kompilator C++? Odpowiedzi nie wysyłać nigdzie, bo każdy ją doskonale zna, jeśli wie, jak skomplikowane jest C++.

Offline ConayR

  • Użytkownik

# Październik 24, 2009, 16:12:16
A co do tego co jest w fazie koncepcyjnej: systemy budujące online widziałem już dobre parę lat temu. Distcc jeszcze wcześniej. A koncepcja jest starsza ode mnie. Z tym, że takie rozważania nie mają sensu bo normalna praca nie polega na make clean && make wykonywanym co 3 minuty.
Nie zrozumieliśmy się - ja nie mówię o rozproszonym budowaniu tylko o kompilowaniu dla wszystkich devboksów w locie poza tymi devboksami (i jasne, przyrostowo). To trochę inna architektura niż to, co oferuje np. distcc (i dlatego to wciąż machanie rękoma i chciejstwo, które moooże za kilka lat będzie możliwe). A co do samego przyrostowego budowania - przy pewnej klasie zmian dla bardzo dużych projektów może nie być możliwe (lub nie dawać żadnego czasowego zysku). Przykładem z życia jest komponent systemowy publikujący nagłówki i liby dla kilkunastu innych projektów. W praktyce to było mniej więcej 10-15% zmian jakich dokonywałem i był po nich konieczny całkiem spory rebuild w ramach weryfikacji przed checkinem.

Offline bies

  • Użytkownik

# Październik 24, 2009, 21:28:14
Słuchajcie, ja naprawdę nie mam zamiaru nikogo przekonywać do używania Boosta, STL, TR1 itp. Ale argument o czasie budowania jest po prostu miękki.
Ja tez akurat (wyjatkowo) nie o Boost czy STL, po prostu niezaleznie od wszystkiego - linkowanie duzych projektow troche trwa. Dodatkowo, czesto nie ma sie swobody wyboru najlepszego kompilatora. Na PS3 masz 2 opcje: SNC (wolny) albo GCC (wolniejszy) :)
Trochę Cię nie rozumiem. Skoro trwa to u Ciebie tak dużo to dlaczego nie próbujesz tego poprawić. Może ramdysk na pliki pośrednie (obj, pliki debuggera -- VC++ ma to chyba osobno). Nie wiem, gdybym miał czekać minutę na kompilację przyrostową to pewnie skończyło by się nawet na profilerze systemowym. Mnie by irytowało.

A co do tego co jest w fazie koncepcyjnej: systemy budujące online widziałem już dobre parę lat temu. Distcc jeszcze wcześniej. A koncepcja jest starsza ode mnie. Z tym, że takie rozważania nie mają sensu bo normalna praca nie polega na make clean && make wykonywanym co 3 minuty.
Nie zrozumieliśmy się - ja nie mówię o rozproszonym budowaniu tylko o kompilowaniu dla wszystkich devboksów w locie poza tymi devboksami (i jasne, przyrostowo). To trochę inna architektura niż to, co oferuje np. distcc (i dlatego to wciąż machanie rękoma i chciejstwo, które moooże za kilka lat będzie możliwe).
Napisz co tak rewolucyjnego jest w tym co opisujesz bo cały czas wydaję mi się, że widziałem to już dobre parę lat temu. Co to znaczy ,,kompilowanie w locie''? Naciskasz kompiluj na maszynie dewelopera i kompiluję Ci się (jakoś, nie ważne jak) używając zasobów silniejszej maszyny? Czy może chodzi Ci o jakąś dziwną pracę nad wspólnym kompilatem?

A co do samego przyrostowego budowania - przy pewnej klasie zmian dla bardzo dużych projektów może nie być możliwe (lub nie dawać żadnego czasowego zysku). Przykładem z życia jest komponent systemowy publikujący nagłówki i liby dla kilkunastu innych projektów. W praktyce to było mniej więcej 10-15% zmian jakich dokonywałem i był po nich konieczny całkiem spory rebuild w ramach weryfikacji przed checkinem.
Nie był potrzebny. Kompilator C++ to program deterministyczny. Jeśli na wejściu ma to samo to na wyjściu będzie to samo. Tylko na wejściu masz sprawdzić preprocesowane źródła. Tak, jak np. działa ccache. Nie miałeś automatyki która to by zapewniała -- dlatego kompilowałeś wszystko.

// edit
Aithne: nie, nie będę używał D. ;D
« Ostatnia zmiana: Październik 24, 2009, 21:30:31 wysłana przez bies »