W tworzeniu gier jest dużo C / C ++, w aplikacjach biznesowych C #. Widziałem, że deweloperzy C / C ++ wyrażają zaniepokojenie tym, jak pojedynczy wiersz kodu tłumaczy się na asemblerze. W .NET niektórzy rzadko chodzą do IL.
W języku C # „mikrooptymalizacja” jest niezadowolona, rzadko i zwykle jest stratą czasu. Wydaje się, że tak nie jest w przypadku tworzenia gier.
Co konkretnie powoduje tę niespójność? Czy gry stale przekraczają granice sprzętu? Jeśli tak, to w miarę jak poprawia się sprzęt, czy możemy oczekiwać, że języki wyższego poziomu przejmą przemysł gier?
Nie szukam debaty na temat wykonalności C # jako twórcy gry. Wiem, że zostało to zrobione do pewnego stopnia. Skoncentruj się na mikrooptymalizacji. W szczególności różnica między twórcami gier a twórcami aplikacji.
AKTUALIZACJA
Przez grę mam na myśli nowoczesny rozwój na dużą skalę. EG MMORPG, Xbox, PS3, Wii ...
źródło
Odpowiedzi:
W aplikacjach biznesowych procesor nie zawsze jest wąskim gardłem. Aplikacja biznesowa spędza większość czasu na oczekiwaniu. Na przykład:
Właśnie dlatego kod optymalizujący wydajność przetwarzania nie dodaje zbyt dużej wartości.
Najważniejsze jest, aby:
źródło
W aplikacjach biznesowych mikrosekunda ma znaczenie. W grach jest to faktem.
Jeśli chcesz, aby gra działała z szybkością 60 klatek na sekundę, masz około 16,67 milisekund na zrobienie wszystkiego, co trzeba zrobić dla tej klatki - wejście, fizyka, logika rozgrywki, dźwięk, sieć, sztuczna inteligencja, rendering i tak dalej; jeśli masz szczęście, będziesz działać przy 30 fps i będziesz mieć luksusowe 33,3 milisekundy. Jeśli ramka potrwa zbyt długo, twoje recenzje ucierpią, twoi gracze wypełnią fora internetowe żółcią i nie sprzedasz tyle, ile możesz (nie wspominając o ciosie swojej dumy zawodowej), a jeśli naprawdę masz pecha znajdzie swój zespół, który będzie zarabiał na życie, kodując aplikacje biznesowe.
Oczywiście, twórcy gier nie martwią się każdą linią, ponieważ dzięki doświadczeniu i przyzwoitemu profilerowi dowiadujesz się, które linie wymagają martwienia się. Z drugiej strony te obawy czasami dotykają rzeczy, które w świecie biznesu byłyby prawdopodobnie uważane za nanooptymalizacje, a nie mikrooptymalizacje.
Nie spodziewaj się, że jakiś język wysokiego poziomu wyrzuci C ++, dopóki nie zaoferujesz porównywalnej i przewidywalnej wydajności.
źródło
Okej, więc widzieliście deweloperów C i C ++ obsesyjnych na punkcie poszczególnych linii. Założę się, że nie mają obsesji na punkcie każdej linii.
Są przypadki, w których chcesz uzyskać maksymalną wydajność, a to obejmuje wiele gier. Gry zawsze starały się przekraczać granice wydajności, aby wyglądać lepiej niż konkurencja na tym samym sprzęcie. Oznacza to, że zastosujesz wszystkie zwykłe techniki optymalizacji. Zacznij od algorytmów i struktur danych i stamtąd. Korzystając z profilera, można dowiedzieć się, gdzie zajmuje najwięcej czasu i gdzie można uzyskać znaczne korzyści z mikrooptymalizacji kilku linii.
Nie dzieje się tak dlatego, że języki zmuszają ludzi do tego, że ludzie wybierają języki na podstawie tego, co chcą robić. Jeśli chcesz wycisnąć ostatnią część wydajności z programu, nie będziesz pisać C # i kompilować do CLR i mieć nadzieję, że kompilator JIT (lub cokolwiek innego) wykona dobrą robotę, piszesz go w czymś, w czym możesz w dużej mierze kontrolować wyjście. Użyjesz C lub C ++ (i prawdopodobnie ograniczonego podzbioru C ++) i studiujesz dane wyjściowe w języku asemblera i wyniki profilera.
Jest wiele osób, które używają C i C ++ i nie przejmują się zbytnio szczegółami tłumaczenia, o ile wydaje się ono wystarczająco szybkie.
źródło
Czy gry stale przekraczają granice sprzętu?
Tak, robią.
Jeśli tak, to w miarę jak poprawia się sprzęt, czy możemy oczekiwać, że języki wyższego poziomu przejmą przemysł gier?
Niezupełnie - ponieważ wraz ze ulepszaniem sprzętu konsumenci oczekują także poprawy gier. Nie oczekują, że ta sama jakość gry będzie opracowywana bardziej wydajnie, ponieważ programiści używali języka wyższego poziomu. Oczekują, że ich skarpety zostaną zdmuchnięte przez każdą nową platformę.
Oczywiście jest pewien ruch. Kiedy byłem chłopcem i po raz pierwszy interesowałem się tworzeniem gier, było to odręczne składanie lub piekło. To była era Commodore 64. W dzisiejszych czasach oczywiście C ++ jest lingua franca większości twórców gier. Rzeczywiście widzieliśmy nawet ruch w kierunku użycia C ++ do kodu silnika i języka skryptowego wyższego poziomu do kodu logiki gry. np. LUA lub silnik Unreal ma swój własny język UnrealScript.
źródło
Jeśli możesz po prostu skompletować aplikację za pomocą kodu wysokiego poziomu i kodu biblioteki, to z pewnością strata czasu. Napisz w przetłumaczonym języku, jeśli chcesz w takim przypadku; nie zrobi dużej różnicy. Jeśli próbujesz wdrożyć najnowocześniejszy silnik globalnego oświetlenia, który wokalizuje zawartość dynamicznej sceny w locie w czasie rzeczywistym, tak jak zrobił to CryEngine 3 , naturalnie nie możesz oderwać się od potrzeby mikrooptymalizacji.
źródło
„Gra” jest dość obejmującym terminem. Gdybyś miał, powiedzmy, MMORPG, mniejsze optymalizacje wpłynęłyby na wielu graczy.
Gracze są i prawdopodobnie zawsze byli przyzwyczajeni do stosunkowo dużej liczby rzeczy, które dzieją się jednocześnie, w czasie rzeczywistym. Pewnie; kiedyś celem było wyczulenie Pacmana lub Tetrisa. Ale wciąż musiały reagować. Noweydays, 3DMMORPG przez zrzucające pakiety połączenia sieciowe.
Z pewnością rozumiem potrzebę optymalizacji.
źródło
Gry nieustannie przetwarzają ogromne ilości tła. Aplikacje biznesowe nie.
źródło
Zawsze uważałem, że termin „mikrooptymalizacja” jest dość niejednoznaczny. Jeśli jakieś zmiany na poziomie instrukcji w układzie pamięci i wzorcach dostępu sprawiają, że coś 80-krotnie przyspiesza od zdyscyplinowanego profesjonalisty mierzącego swoje punkty aktywne bez zmniejszania złożoności algorytmicznej, to czy jest to „mikrooptymalizacja”? Dla mnie jest to „mega optymalizacja”, by zrobić coś 80 razy szybciej w przypadku użycia w świecie rzeczywistym. Ludzie zwykle mówią o takich rzeczach, ponieważ takie optymalizacje mają efekty mikroskopowe.
Nie pracuję już w gamedev, ale pracuję w VFX w obszarach takich jak śledzenie ścieżek, i widziałem wiele implementacji BVH i drzew KD, które przetwarzają ~ 0,5 miliona promieni na sekundę na złożonej scenie (i to z ocena wielowątkowa). Z grubsza mówiąc, zwykle widzę prostą implementację BVH w kontekście raytracingu przy prędkości poniżej 1 miliona promieni / s, nawet przy ocenie wielowątkowej. Z wyjątkiem Embree ma BVH, który może przetwarzać ponad 100 milionów promieni na tej samej scenie przy użyciu tego samego sprzętu.
Wynika to całkowicie z „mikrooptymalizacji”, że Embree jest 200 razy szybszy (ten sam algorytm i struktura danych), ale oczywiście powodem, dla którego jest o wiele szybszy, jest to, że programiści w firmie Intel to profesjonaliści, którzy opierają się na swoich profilach i pomiarach oraz naprawdę dostroił obszary, które miały znaczenie. Nie zmieniali kodu nie chcąc wyjść z przeczuć i nie wprowadzali zmian, które wprowadziły ulepszenia o 0,000000001% kosztem znacznego pogorszenia łatwości konserwacji. Były to bardzo precyzyjne optymalizacje zastosowane w rozsądnych rękach - mogły być mikroskopijne pod względem skupienia, ale makroskopowe pod względem efektu.
Oczywiście w zależności od wymagań dotyczących szybkości klatek w czasie rzeczywistym w grach, w zależności od tego, w jaki sposób pracujesz z silnikiem gry na wysokim lub niskim poziomie (nawet gry wykonane przy użyciu UE 4 są często implementowane przynajmniej częściowo w skrypcie wysokiego poziomu, ale nie powiedzmy najbardziej krytycznych części silnika fizyki), mikrooptymalizacje stają się praktycznym wymogiem w niektórych obszarach.
Innym bardzo podstawowym obszarem, który nas otacza na co dzień, jest przetwarzanie obrazu, takie jak rozmycie zdjęć w wysokiej rozdzielczości w czasie rzeczywistym i być może wykonywanie na nich innych efektów w ramach przejścia, które prawdopodobnie wszyscy gdzieś widzieliśmy, być może nawet efekt systemu operacyjnego. Nie zawsze można zaimplementować takie operacje na obrazie od zera do pętli przez wszystkie piksele obrazu i oczekiwać takich wyników w czasie rzeczywistym przy pasujących częstotliwościach klatek. Jeśli chodzi o procesor, zwykle patrzymy na SIMD i mikro-tuning, lub na shadery GPU, które zwykle wymagają sposobu myślenia na poziomie mikro do skutecznego pisania.
Wątpię raczej, aby postępy w zakresie samego sprzętu były w stanie to zrobić, ponieważ wraz z postępem sprzętu rosną również instrukcje i technologia (np. Fizyka na GPU), techniki i oczekiwania klientów w zakresie tego, co chcą zobaczyć, i konkurencji w sposoby, które często powodują, że programiści znów przechodzą na niski poziom, tak jak nawet w przypadku twórców stron internetowych, którzy teraz piszą niskopoziomowe moduły cieniujące GLSL w WebGL (tego rodzaju tworzenie stron internetowych jest prawdopodobnie nawet niższe niż dziesięć lat temu, ponieważ GLSL jest językiem C o bardzo niskim poziomie, a dziesięć lat temu nigdy bym nie zgadł, że niektórzy twórcy stron internetowych chcieliby pisać takie cieniujące moduły GPU).
Jeśli będzie sposób na przejście do obszarów wyższego poziomu w obszarach krytycznych pod względem wydajności, będzie musiał uzyskać więcej z oprogramowania, kompilatorów i narzędzi, które mamy, tak jak ja to widzę. Problemem w najbliższej przyszłości nie jest to, że sprzęt nie jest wystarczająco silny. Ma to więcej wspólnego z tym, że nie możemy znaleźć sposobu, aby najskuteczniej z nim rozmawiać za każdym razem, gdy zmienia się i rozwija, bez powrotu do swojego własnego języka. W rzeczywistości to szybkie tempo zmian sprzętowych sprawia, że programowanie na wysokim poziomie jest raczej nieuchwytne dla tych obszarów, jak widzę, ponieważ jeśli hipotetycznie nasz sprzęt przestanie się pojawiać niespodziewanie przez następne dziesięciolecia,
Zabawne jest to, że w dzisiejszych czasach, gdy pracuję w obszarach krytycznych pod względem wydajności, muszę nieco myśleć o niskim poziomie, niż zacząłem (mimo że zacząłem w erze Borland Turbo C DOS). Ponieważ wtedy pamięć podręczna procesora prawie nie istniała. Były to głównie pamięci DRAM i rejestry, co oznaczało, że mogłem skupić się bardziej na złożoności algorytmicznej i pisać powiązane struktury, takie jak drzewa, w bardzo prosty sposób, bez większego uszczerbku dla wydajności. Obecnie szczegóły niskiego poziomu pamięci podręcznej procesora dominują w moim prawie tak samo, jak sam algorytm. Podobnie mamy maszyny wielordzeniowe, które zmuszają nas do myślenia o wielowątkowości, atomach i muteksach oraz bezpieczeństwie wątków i współbieżnych strukturach danych itd., Co powiedziałbym, pod wieloma względami, o wiele niższym poziomie zainteresowania (ponieważ w, nie po ludzku intuicyjnie) niż wtedy, gdy zaczynałem.
Dziwne, wydaje mi się to teraz bardzo prawdziwe. Wydaje mi się, że bardziej wpływają na mnie niżej złożone 30 lat temu złożoności i szczegóły sprzętu, niż starałem się 30 lat temu, starając się zdjąć okulary nostalgiczne. Oczywiście moglibyśmy tutaj porozmawiać o asemblerze i musieliśmy poradzić sobie z pewnymi krwawymi szczegółami, takimi jak XMS / EMS. Ale w przeważającej części powiedziałbym, że wymagałem mniej złożoności i świadomości sprzętu i kompilatora niż wtedy, gdy pracuję w obszarach krytycznych pod względem wydajności. I wydaje się to prawie prawdziwe w całej branży, jeśli odłóżmy na bok jak pisanie
if/else
stwierdzenia w nieco bardziej czytelny dla człowieka sposób i zastanów się, ile osób obecnie myśli więcej o szczegółach niższego poziomu sprzętu (od wielu rdzeni przez procesory graficzne, przez SIMD po pamięć podręczną procesora i wewnętrzne szczegóły tego, jak ich kompilatory / tłumacze / biblioteki działają itd.).Wysoki poziom! = Mniej wydajny
Wracając do tego pytania:
Dla mnie nie chodzi o sprzęt. Chodzi o optymalizatory i narzędzia. Kiedy zaczynałem, ludzie praktycznie pisali wszystkie gry konsolowe w asemblerze, a wtedy istniała prawdziwa przewaga wydajności, szczególnie biorąc pod uwagę brak wysokiej jakości kompilatorów generujących 6502.
Gdy optymalizatory kompilatory C stały się inteligentniejsze w swoich optymalizacjach, zaczęły osiągać punkt, w którym kod wyższego poziomu napisany w C konkurował, a czasami nawet przewyższał kod napisany przez najlepszych ekspertów w wielu dziedzinach (choć nie zawsze), i to sprawiło, że przyjęcie C było przynajmniej bezproblemowe, przynajmniej w przypadku kodowania gry. Podobna zmiana stopniowo nastąpiła w pewnym momencie w C ++. Przyjęcie C ++ było wolniejsze, ponieważ uważam, że wzrost wydajności przejścia od montażu do C mógłby prawdopodobnie osiągnąć jednomyślne porozumienie ze strony gamedevów piszących nietrywialne gry całkowicie w ASM, w przeciwieństwie do przejścia z C do C ++.
Ale te zmiany nie wynikały z tego, że sprzęt stał się bardziej wydajny, ponieważ optymalizatory dla tych języków powodują, że obniżenie poziomu jest w dużej mierze (choć nie zawsze całkowicie, są pewne niejasne przypadki) przestarzałe.
Jeśli potrafisz sobie wyobrazić hipotetyczny scenariusz, w którym moglibyśmy napisać kod w kodzie najwyższego poziomu, jaki można sobie wyobrazić, bez obawy o wielowątkowość, procesory graficzne lub błędy pamięci podręcznej itp. (A może nawet o określone struktury danych), a optymalizator był jak sztuczna inteligencja inteligentny i potrafiłby wymyślić najbardziej efektywne układy pamięci, przestawiając i kompresując nasze dane, wymyśliłby, że może korzystać z niektórych GPU tu i tam, zrównoleglać trochę kodu tu i tam, użyć trochę SIMD, może sam się profilować i dalej optymalizować IR jako nas, ludzi odpowiadając na hotspoty profilerów, i zrobiło to w sposób, który pokonuje najlepszych na świecie ekspertów, to nie byłoby problemu, nawet dla osób pracujących w obszarach najbardziej krytycznych pod względem wydajności, aby go przyjąć ... i to jest postęp pochodzące z absurdalnie inteligentnych optymalizatorów, a nie szybszego sprzętu.
źródło
Masz tutaj problem terminologiczny. Używasz tych słów poprawnie, ale twórcy gier i ludzie biznesu używają tego samego terminu na dwa bardzo różne sposoby.
Dla biznesu „mikrooptymalizacja” oznacza przyspieszenie bardzo małego kroku w całym procesie biznesowym realizowanym przez oprogramowanie. Powodem, dla którego czuje się niezadowolony, jest zazwyczaj jeden z:
Tworzenie gier to inna bestia. „mikrooptymalizacja” oszczędza niewielką ilość czasu w funkcji lub procedurze.
Więc w biznesie nikomu nie zależy, czy forma 4-etapowego procesu biznesowego pojawi się w 0,6 sekundy lub 0,5 sekundy. Podczas grania ważne jest, aby rutyna, która zajmuje 200 ms, mogła zostać zredukowana do wykonania w 100 ms.
Chodzi o wartość dostarczoną klientowi, potrzeby klienta oraz stosunek kosztów do korzyści zmiany.
źródło
Ma to związek z tym, dlaczego to narzędzie zostało wybrane do określonego zadania.
Golfiści będą mieli obsesję na punkcie kierunku i siły, jaką przyłożą za pomocą miotacza, nie tyle kiedy używają kierowcy.
Dlaczego? Ponieważ są to różne rodzaje ujęć. Do jazdy chcesz wsiąść na tor wodny z maksymalną odległością. W przypadku putta chcesz go dokładnie umieścić w dołku.
To samo dotyczy tutaj. Twórcy gier wybierają C ++, ponieważ daje im kontrolę nad wydajnością różnych operacji. Jeśli to wybierzesz, będziesz chciał to wykorzystać.
źródło
Większość aplikacji biznesowych jest napisanych jako narzędzia wewnętrzne. Oczekiwania dotyczące użyteczności tego narzędzia są znacznie niższe niż w przypadku oprogramowania sprzedawanego masowym klientom. Dość powszechne jest, że wewnętrzna aplikacja biznesowa ma menu i okna dialogowe, które powoli reagują na kliknięcia myszą, okna przerysowane z opóźnieniem, a nawet GUI napisane w Swing (horror!). Wynika to z wielu powodów (ważniejsze jest to, że oprogramowanie można dostosowywać niż to, że jest bardzo „szybkie”), użytkownicy oprogramowania nie mają wyboru, czy używać danego oprogramowania, czy też nie, ludzie, którzy decyzja o instalacji oprogramowania nie korzysta z niego samodzielnie ...). Konsekwencją tego wszystkiego jest to, że twórcy tych narzędzi nie spędzają dużo czasu na optymalizacji czasu reakcji aplikacji, ale bardzo zależy na rozszerzalności i liczbie funkcji. Różna baza klientów => różne cele projektowe => inna metodologia.
Pamiętaj, że aplikacja biznesowa skierowana do masowego odbiorcy, taka jak Excel, jest mocno zoptymalizowana.
źródło