Każdy język programowania ma swoją standardową bibliotekę kontenerów, algorytmów i innych przydatnych rzeczy. W przypadku języków takich jak C #, Java i Python korzystanie z języka bez jego standardowej biblioteki jest praktycznie nie do pomyślenia .
Jednak w wielu grach w C ++, nad którymi pracowałem, albo wcale nie używaliśmy STL, używaliśmy niewielkiej jego części, albo korzystaliśmy z własnej implementacji. Trudno powiedzieć, czy była to słuszna decyzja dla naszych gier, czy po prostu z powodu nieznajomości STL.
Więc ... czy STL dobrze pasuje, czy nie?
Odpowiedzi:
Kiedy pracowałem nad profesjonalnym tworzeniem gier, STL był zbyt niedojrzały i nadęty. Ale to było> 10 lat temu.
Teraz pracuję w symulacji wojskowej, która ma jeszcze surowsze wymagania dotyczące wydajności (np. Liczba klatek na sekundę nigdy nie spadnie poniżej niektórych FPS). W symulacji wojskowej STL jest używany wszędzie.
Niektórzy ludzie, którzy mówią ci, aby nie używać STL, argumentują, że nie zawsze jest to idealne lub nawet najlepsze rozwiązanie problemu. Ale to nie jest odpowiedź na pytanie. Pytanie powinno brzmieć: Czy jest coś z natury złego w używaniu STL w grach? Powiedziałbym, że nie, STL jest w większości przypadków lepszą implementacją niż to, co wymyśliłby użytkownik na własną rękę.
Po prostu upewnij się, że wiesz, jak korzystać z STL i używać go w swojej grze. Przeczytaj kilka książek i spójrz na kod implementacyjny w STL, którego używasz.
źródło
if(stream.nextCharacter() == '#') stream.skipLine();
Powiedziałbym, że z góry mojej głowy lepiej jest używać STL, chyba że wiesz dokładnie, dlaczego nie chcesz go używać.
Oto kwestia STL: jest rozwijana przez ludzi mądrzejszych od ciebie. To nie ma być obraźliwe ani nic innego, po prostu STL jest rozwijany przez ludzi, których praca polega na budowaniu STL. Będzie on praktycznie tak szybki, jak pozwala na to platforma, i będzie ogólnie znacznie bardziej niezawodny niż rozwiązanie domowej roboty (i powinno to być równie ważne, jeśli nie martwisz się o czystą szybkość - ponieważ Twoja gra potrzebuje solidność nieco większa niż potrzebujesz prędkości; ta druga nie ma znaczenia bez pierwszej).
Skargi, że STL wymusza „wąskie spojrzenie na świat”, wydają mi się trochę głupie. To są pojemniki. Mają ograniczony zestaw operacji, ponieważ kontenery mają ograniczony zestaw operacji. Co robisz, że się z tym nie kręci?
źródło
Widziałem bardzo niewiele powodów, aby nie używać STL do gier.
W przypadku problemów z alokacją pamięci wiele osób nie wie o tym, ale możesz napisać niestandardowe alokatory dla swoich klas kontenerów STL. Alokatory to w zasadzie klasy zasad, które przekazujesz do szablonów, aby określić sposób wykonywania alokacji. Korzystając z nich, zwykle możesz obejść wszelkie problemy z pamięcią, które są problematyczne na wybranej platformie.
Oczywiście, jeśli używasz STL i robisz głupie rzeczy, takie jak mapy ciągów znaków do dużych typów, które nie są wskaźnikami, masz większe problemy.
źródło
google::sparse_map
lub pisanie własnych.Domyślna STL ma sporo problemów, które utrudniają korzystanie z niej, szczególnie jeśli chodzi o wyrównanie pamięci.
Dostosowany wariant, taki jak EA STL, jest specjalnie zaprojektowany do gier i może zapewnić znacznie lepszą wydajność pamięci i użyteczność konsoli. Stało się open source w 2016 roku, zgodnie z klauzulą BSD-3, z repozytorium na GitHub .
źródło
std::vector
które przesłoniło domyślny alokator.Oto co Mike Acton (Dyrektor silnika Insomniac Games z Spyro the Dragon, Ratchet & Clank oraz Resistance sławy) miał do powiedzenia na temat tego, kiedy zapytałem tutaj . Zauważ, że zapytano go zarówno o STL, jak i ogólnie Boost w związku z użyciem go w grze.
STL / Boost, czy należy do gamedev? Jeśli tylko części, które?
Zauważyłem również, że większość profesjonalnych twórców gier dąży bardziej do C niż C ++.
źródło
Jeśli z jakiegoś powodu przepisujesz coś, co już istnieje w STL, przestań . Użyj STL.
STL został zoptymalizowany przez lata analizy i czasu, i jest to bezpieczny zakład, że prawdopodobnie nie zamierzasz napisać czegoś bardziej wydajnego. Nie oznacza to, że powinieneś używać STL tam, gdzie możliwe jest prostsze rozwiązanie (tj. Użyć tablicy, gdy masz znaną ilość rzeczy, a nie stl :: list), ale jeśli piszesz własną implementację mapy ( podstawowa struktura danych, a nie mapa świata), robisz to źle.
źródło
std::sort
ogół używa introsortu pod spodem, niezwykle szybkiego i na tyle złożonego, że nie będziesz chciał tego zrobić sam.unordered_map
albo w C ++ 11, albo oba są zbyt wolne, to, czego chcesz, to otwarta mapa mieszająca, taka jak google :: sparse_map lub twoja.Czy STL nadaje się do gier? Zdecydowanie. Gry to złożone oprogramowanie, STL zapewnia funkcje pomagające zarządzać złożonością, więc jest dobrze.
Czy dobrze pasuje do twojej platformy? Niekoniecznie. Jeśli piszesz dla konsoli, musisz bardzo uważać na użycie pamięci i pamięci podręcznej. STL nie ułatwia tego.
Myślę, że zbyt często mylimy „gry” z „wysokowydajnymi grami czasu rzeczywistego, które działają na wbudowanym lub niestandardowym sprzęcie”, ale ważne jest, aby wprowadzić rozróżnienie. Jeśli piszesz grę systemu Windows, która nie próbuje działać w trybie pełnoekranowym ze stałą prędkością 60 klatek na sekundę, nie ma powodu, aby unikać narzędzi udostępnianych przez standardową bibliotekę.
źródło
Wiem, że na przyjęcie jest już późno, ale zmiany czasu i odpowiedzi pozostają w pobliżu. C ++ 11 ma dość duże zmiany, z których wiele ma na celu zwiększenie wydajności C ++ i biblioteki standardowej. Wygląda na to, że ci, którzy nie używają STL lub Boost, również nie nadążają za nowymi standardami, pozostawiając rozwiązania domowe bez istotnych ulepszeń, oczywiście nie zawsze tak jest.
Użyłem STL do każdego projektu od połowy lat 90. do dziś, z wyjątkiem krótkiego czasu w EA. Myślę, że strona anty-STL miała jakieś racjonalnie uzasadnione powody, aby jej nie używać. Te w dużej mierze zniknęły. Niestandardowe alokatory to jedno rozwiązanie, użycie rezerwy to drugie, a nieprzekazywanie wartości po wartości to trzecie, ale są one dość proste i każdy programista powinien je znać. Ważniejsze jest jednak użycie algorytmów. Autorzy kompilatorów dokładnie wiedzą, co robi funkcja for_each () i mogą zoptymalizować kod. Nie może się to zdarzyć w przypadku pętli domowej. For_each () na obiekcie const jest jeszcze lepszy. Microsoft optymalizuje for_each na wiele sposobów, w tym serializacji. Mają także bibliotekę AMP, która ma parallel_for_each (). Jeśli masz szansę, porozmawiaj o tym z inżynierami kompilatorów. Kompilatory konsoli zoptymalizują to, co zostanie wykorzystane, więc „ trochę problemu z jajkiem i kurczakiem. Microsoft idzie bardzo ciężko z C ++ 11 i następny XBox nie będzie inaczej. Nie mam pojęcia o PS4, jeszcze go nie mamy.
Niestandardowe alokatory to jeden ze sposobów radzenia sobie z problemem z pamięcią, ale inną (często pomijaną) opcją jest użycie nowej i usunięcia na podstawie klasy. W ten sposób można uzyskać ogromny wzrost wydajności.
Pogląd, że Boost i STL mają wąski pogląd na rozwiązywanie problemów, jest czystym szaleństwem. Jestem zaskoczony, jak wiele rzeczy w STL i Boost można dostosowywać za pomocą cech i zasad. Wyszukaj ciąg znaków niezależny od wielkości liter jako przykład.
Jeśli chodzi o długi czas połączenia i rozdęcie kodu, nowy szablon zewnętrzny powinien w tym pomóc. Generalnie uważam, że długie czasy kompilacji wynikają z nadmiernego sprzężenia i niewłaściwego użycia pch.
Najbardziej przekonującym powodem używania STL w porównaniu z samodziałem jest to, że są miliony ludzi, którzy mogą ci pomóc z STL. Jak zawsze, nie optymalizuj przedwcześnie i testuj, testuj, testuj.
źródło
To gorący temat w tworzeniu gier. Ja osobiście tego nie polecam, z wyjątkiem być może EASTL, jak wspomniano powyżej. Mam dwa główne problemy ze STL (technicznie „Standardowa biblioteka C ++”, ponieważ STL nie jest już nazwą) w grach. 1) Dynamiczny przydział pamięci często marnuje dużo czasu działania w grach, gdy używany jest STL. 2) Wykorzystanie STL zachęca do podejścia do architektury gier z wykorzystaniem szeregu struktur, podczas gdy podejście do struktur jest znacznie bardziej przyjazne dla pamięci podręcznej.
źródło
To zależy. Jak duży jest projekt, jakie platformy i jaka jest oś czasu?
Jeśli pracujesz nad dużym projektem, na platformach z ograniczonymi zasobami, ze znaczną osią czasu i budżetem, możesz zaoszczędzić sobie wiele kłopotów, unikając nieuchronnego piekła, które będzie patrzeć na pół miliona kodów kreskowych, które są zaśmiecony STL, nie może utrzymać liczby klatek na sekundę powyżej 30, zjada wystarczającą ilość pamięci RAM, aby zmieścić kilka dodatkowych zasobów i zajmuje 2 godziny.
W innych sytuacjach jednak STL, a nawet Boost mogą być bardzo przydatne, gdy są odpowiednio stosowane. Pracowałem nad tytułami, które wykorzystywały wybór STL / Boost i były absolutnym marzeniem do kodowania: mniej błędów / wycieków i łatwy w utrzymaniu kod oznacza więcej czasu na zabawę nowych funkcji! Szczególnie w przypadku projektów hobbystycznych jest to ogromna wygrana w dziale motywacji.
Wiedz, kiedy wymieniać wyniki dla wygody!
źródło
IMHO Powiedziałbym, że jest dobrze dopasowany, ponieważ STL już działa dobrze i jest zoptymalizowany do zadań, do których został stworzony. Poza tym pracujesz nad grą, więc skorzystaj z dostępnych narzędzi, które ułatwią Ci życie, a Twój kod będzie mniej podatny na błędy.
Po co zawracać sobie głowę odkrywaniem koła, kiedy możesz pracować nad czymś innym, jak sztuczna inteligencja gry, wrażenia użytkownika lub jeszcze lepsze; testowanie i debugowanie?
źródło
STL jest absolutnie w porządku do użytku w grach, o ile dobrze go rozumiesz. Nasz silnik korzysta z niego dość szeroko i nigdy nie stanowiło to problemu. Nie mam doświadczenia w tworzeniu konsoli, co może być zupełnie inną historią, ale jest dobrze obsługiwane na wszystkich platformach PC (Windows / Mac / Linux).
Najważniejsze jest zrozumienie, jakie są mocne i słabe strony każdego rodzaju pojemnika i wybranie odpowiedniego pojemnika do wykonywanej pracy.
źródło
Mój były pracodawca przeszedł z używania solidnego zestawu niestandardowych klas kontenerów na STL. Czas kompilacji wzrósł i zmniejszyła się łatwość debugowania, oba dość znacząco. Gdybyśmy zaczynali od zera, STL (być może lepiej użyty) prawdopodobnie miałby sens, ale nigdy nie było dla mnie jasne, że przestawiliśmy się na STL, co uzasadniałoby wyrzucenie działającego, szybkiego, debugowalnego kodu.
W przypadku moich osobistych projektów to, czy STL pasuje, czy nie, zależy od projektu. Jeśli próbuję wykonać pewne prace zoptymalizowane pod kątem danych, zoptymalizowane pod kątem dostępu do pamięci i pamięci podręcznej w stylu Mike'a Actona, przynajmniej pomyślę o rozwinięciu własnych niestandardowych struktur danych. Jeśli prototypuję jakieś algorytmy lub rozgrywkę i nie dbam o wydajność, skalowalność, platformę docelową itp., Automatycznie zdobędę STL.
źródło
Moim 2 centami jest to, że STL działa dobrze. Opracowuję silnik gry 3D (nie jakości AAA, ale wystarczająco zaawansowany - skrypty typów jednostek, odroczony renderer, zintegrowana fizyka Bullet) na PC i nie widziałem, aby kontenery stały się głównym wąskim gardłem. Nieprawidłowe użycie 3D API i słabe algorytmy były najlepszymi celami (ustalonymi przez profilowanie!) Za każdym razem, gdy wchodziłem i próbowałem uzyskać nieco większą wydajność.
źródło
Zbudowałem gry przy użyciu STL i podoba mi się to, i wydaje się, że działa dobrze.
źródło
Dobre pytanie! Bardziej szczegółowe pytanie brzmi: jakie są niektóre typowe wymagania gry, których nie można spełnić za pomocą STL i Boost.
Z mojego doświadczenia wynika, że ścisłe ograniczenia pamięciowe sprzętu konsoli sprawiają, że każdy kontener o dynamicznej wielkości jest złym pomysłem, niezależnie od tego, jak sprytny jest twój niestandardowy alokator. Kontenery, które nie mają umyślnych granic, zachęcają programistów do pisania kodu, który nie ogranicza granic ich zestawów danych. W zależności od niezliczonych zmiennych, które są trudne do śledzenia, możesz przekroczyć ograniczenia pamięci. Mam przeczucie, że jest to jedna z głównych przyczyn niestabilności we współczesnych grach.
Dodatkowo, nadużywanie szablonów może prowadzić do bardzo długich czasów kompilacji w dużej bazie kodu i spowoduje powiększenie rozmiaru pliku wykonywalnego, aby nie mieścił się już w pamięci podręcznej, powiedzmy, pomocniczego rdzenia na ps3.
Jednak w przypadku projektowania wyłącznie na komputery PC STL i Boost są bardzo dobre. Chociaż ogólne rozwiązania nie zawsze są idealne, często są wystarczająco dobre. Twoje pierwsze rozwiązanie problemu prawie nigdy nie jest idealne i poprawiasz lub zastępujesz niedoskonałości, dopóki nie będą wystarczająco dobre.
źródło
STL dobrze pasuje do twojej gry, jeśli STL dobrze pasuje do twojej gry.
Podobnie jak w przypadku wszystkich wyborów technologicznych dokonywanych podczas programowania, musisz rozważyć zalety i wady - czy stworzenie własnej biblioteki zapewni mi bardziej korzystne wykorzystanie pamięci, wydajność i produktywność niż zwykłe korzystanie z STL? Możliwie; chociaż równie łatwo jest stworzyć
vector
implementację, która zużywa więcej pamięci, jest wolniejsza i wymaga dużej konserwacji, aby zachować funkcjonalność w porównaniu z tym, co już istnieje.Ludzie nie powinni unikać używania STL w swoich grach, ponieważ inni ludzie unikają używania STL w grach; powinni unikać korzystania z niego, jeśli rozważą wszystkie swoje opcje i naprawdę wierzą, że kolejne wdrożenie poprawi jakość ich produktu.
źródło
vector
niż ludzie STL. Zanim to zrobisz, nie będziesz już myśleć, że musisz! :-)Jak w przypadku większości pytań, odpowiedź nigdy nie brzmi „tak czy nie”, czarny lub biały. STL dobrze pasuje do niektórych problemów, używanie go do tych problemów powinno być w porządku. Błędem jest zakładanie, że jest bezużyteczny, ale błędem jest również zakładanie, że właściwe jest stosowanie go w każdej sytuacji.
Największym problemem, na który należy zwrócić uwagę podczas korzystania z STL podczas tworzenia gier, jest przydzielanie pamięci. Domyślne alokatory STL wydają się nie pasować do preferowanych strategii alokacji przy tworzeniu gier. Oczywiście można zastosować niestandardowe alokatory, ale to sprawia, że cały pomysł jest mniej atrakcyjny, jeśli zastanawiasz się, czy dodać STL do bazy kodu innej niż STL.
Dodaj do tego, że jeśli twoja baza kodu jest inna niż STL, możesz nie mieć nikogo, kto zna wystarczająco STL lub koncepcje szablonów, aby poprawnie zaimplementować niestandardowe alokatory.
źródło
Myślę, że dyskusję tę można streścić w następujący sposób:
przeciętnie napisany kod specyficzny dla aplikacji <dobrze napisany kod ogólnego przeznaczenia <dobrze napisany kod specyficzny dla aplikacji
Każdy, kto ma własne rozwiązanie należące do kategorii 3, z pewnością zna odpowiedź na pierwotne pytanie dotyczące konkretnego problemu. STL wpada do kategorii 2. Więc dla kogoś, kto potrzebuje, aby zadać pytanie, „powinny I użyć STL”, odpowiedź brzmi: prawdopodobnie tak.
źródło
STL jest w porządku do użytku na PC, ponieważ jego zaawansowany system pamięci wirtualnej sprawia, że potrzeba starannego przydzielania pamięci jest nieco mniej istotna (chociaż trzeba być bardzo ostrożnym). Na konsoli, z ograniczoną pamięcią wirtualną lub bez niej oraz z nadmiernymi kosztami braku pamięci podręcznej, prawdopodobnie lepiej nie pisać niestandardowych struktur danych, które mają przewidywalne i / lub ograniczone wzorce alokacji pamięci. (I na pewno nie pomylisz się, robiąc to samo w projekcie gry na PC).
źródło
Myślę, że to pytanie jest naprawdę większym pytaniem bez pytania - czy powinienem używać X w moim Y ? Jedynym sposobem, aby naprawdę odpowiedzieć, jest wypróbowanie go samemu. Dla każdej osoby, która twierdzi, że X działa świetnie, znajdziesz kogoś, kto mówi, że to okropne. I oba mają rację - do swojego projektu.
Wspaniałą rzeczą w oprogramowaniu, w przeciwieństwie do większości innych dyscyplin, jest to, że zawsze możesz później zmienić rzeczy, jeśli okaże się, że nie działa tak, jak byś tego chciał. Dowiesz się później, że STL nie działa dla Ciebie w tym projekcie? Rozerwij to, umieść coś innego na swoim miejscu. Nie podoba ci się, jak podzieliłeś obowiązki między swoje przedmioty? Refaktor. Nie podoba ci się, że używałeś obiektów? Zastąp je prostymi metodami C. Nie podoba ci się, że wszystko jest przechowywane w strukturach i metodach manipulowania nimi? Zamień je na obiekty C ++.
źródło
Mówię nie do STL. Mój powód jest dość prosty:
Uważam, że liczenie iteracji ma najwyższe znaczenie, więc po prostu trzymam się z dala od STL i wszelkich innych technik programistycznych, które spowalniają iteracje (jak na przykład architektura lub języki skryptowe, które należy skompilować).
Kosztowne iteracje prowadzą do ogromnych zespołów programistów, którzy próbują załatwić sprawy przy bardzo niewielkiej liczbie rzeczy. Widziałem to i słyszałem, a jednym z winowajców wydaje się być czas kompilacji bibliotek szablonów.
źródło