.[ ČeskéHry.cz ].
Vyjimky (Exceptions) v hernim prumyslu
Jdi na stránku 1, 2, 3, 4, 5  Další
 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
LukeMak



Založen: 08. 02. 2013
Příspěvky: 16

PříspěvekZaslal: 15. červen 2013, 18:57:05    Předmět: Vyjimky (Exceptions) v hernim prumyslu Odpovědět s citátem

Cau, cetl jsem v knize zamerene na architekturu enginu, kterou napsal byvaly zamestnanec Nauhgty Dog a dalších studii, ze obecne "vypinali" vyjimky a vubec je nepouzivali (hlavne teda prej v Naughty Dog - pri vyvoji na konzole). Dost me to prekvapilo, chapu, ze je tam vyssi rezie, ale nemyslel jsem si, ze vyjimky uplne ignoruji. Pouziti pri realtime renderingu bych taky vyloucil, ale takove chyby jako nepodarilo se nacist nejaky soubor, na to si myslim, ze jsou výjimky fajn... Co si o tom myslite?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
perry



Založen: 28. 07. 2009
Příspěvky: 879

PříspěvekZaslal: 15. červen 2013, 19:18:24    Předmět: Odpovědět s citátem

Osobně výjimky nepoužívám v C/C++ nikde, takže se tomu ani nedivím. Hodně funkcí (hlavně práci se soubory) navíc stačí kontrolovat na návratovou hodnotu, typicky když se něco podělá, vrací NULL. Navíc v renderingu, když se to pokazí výjimkou, která stejně nejde vyřešit, tak jestli to napíše chybu a vypne se to, nebo to rovnou spadne / zatuhne, je celkem jedno.. tak jako tak se to musí pustit znovu. Navíc čas spotřebovaný na případnou kontrolu se nevrátí. Je to tedy můj osobní pohled na věc, nejsem profi game-developer.

PS: Jako v Javě je to věc jiná, tam ty výjimky musím "naprasit" i když nechci.
_________________
Perry.cz
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Tringi



Založen: 28. 07. 2007
Příspěvky: 289

PříspěvekZaslal: 15. červen 2013, 20:15:45    Předmět: Odpovědět s citátem

Je to jako se vším, nesmí se to přehánět, s výjimkami obzvláště.

Určitě je vhodné je využít ve spojení s RAII, ale ještě lépe je přehodnotit návrh tak, aby vůbec nemohly vzniknout, příklad: Mám-li RTS a každý vzniknuvší tank alokuju jako objekt, pak musím řešit, co se stane, když dojde paměť. Jakkoliv se může zdát použití velkého, předběžně rezervovaného, pole hloupým, nemusím zmíněný problém řešit a můžu z jeho velikosti rovnou říct hráči, kolik RAM na hru potřebuje. Prakticky vše ostatní (než zajištění zdrojů) se dá řešit logikou lokálně místo výjimkami.

Výjimky taky něco stojí, ale ne až tolik, jak se často démonizuje. GCC/MinGW nedávno přešlo z implementace, která stála nějaké instrukce na každém stack-frame (SJLJ) na implementaci, která je rychlejší ale stojí místo v EXE/paměti na typové tabulky (DWARF2). Výhody SEH implementace (MSVC) z hlavy nevím.
Definitivně ale výjimky nemají co dělat v nejužších herních smyčkách, které se provádí sta-tisíckrát za snímek.
_________________
WWW | GitHub | TW
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Vilem Otte



Založen: 18. 09. 2007
Příspěvky: 462
Bydliště: Znojmo - Sedlesovice, Kravi Hora

PříspěvekZaslal: 15. červen 2013, 21:16:32    Předmět: Odpovědět s citátem

Vyjímky nepoužívám, napsat je stojí mnohem více úsilí než klasické asserty (zvláště pokud si upravíte assert ať vám třeba dá výstup do logu).

Přeci jen:
kód:
try
{
   ... stuff ...
}
catch
{
   ... stuff ...
}
finally
{
   ... stuff ...
}


Je sakra delší kód než hloupý ale účinný
kód:
assert(cond);

_________________
Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail Zobrazit autorovi WWW stránky
michalferko



Založen: 29. 09. 2008
Příspěvky: 83

PříspěvekZaslal: 15. červen 2013, 22:12:25    Předmět: Odpovědět s citátem

Ja vynimky pouzivam iba pri veciach, ktore znamenaju okamzite ukoncenie aplikacie (tj. neskompiluje sa shader, alebo je poskodeny subor). Cize mam v celej aplikacii jeden try-catch blok.

Pokial viem (opravte ma prosim ak trepem), tak vynimky uberaju na vykone az ked nejaka vynimka nastane.

V mojom pripade sa teda stava velmi malokedy ze vynimka nastane, a vacsinou to pouzivam pri debugovani, ale v realnom release aplikacie pravdepodobne vynimka nenastane (pokial mi uzivatel nebude babrat so subormi aplikacie). Vlastne okrem inicializacie aplikacie mi to ani nema prilis kde hodit vynimku.

Beriem to ako vyborne sprehladnenie kodu a netreba riesit navratove hodnoty cez kopu funkcii. Ak to naozaj nie je nutne, tak sa im radsej vyhnem. Neviem si predstavit rozumne pouzitie vynimiek, kde by hrozilo ze nastanu tisicky krat za sekundu.
_________________
Moje minihry a ine projekty
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
OndraSej



Založen: 28. 07. 2007
Příspěvky: 765
Bydliště: Brandýs nad Labem

PříspěvekZaslal: 16. červen 2013, 06:55:31    Předmět: Odpovědět s citátem

Vilem Otte napsal:
Vyjímky nepoužívám, napsat je stojí mnohem více úsilí než klasické asserty (zvláště pokud si upravíte assert ať vám třeba dá výstup do logu).


Tady srovnáváš jablka s hruškama... assert(nepo->aloSeTo()) bys měl srovnávat spíš s if (po->aloSeTo()) throw some_error(), to z hlediska počtu řádek už tak velký rozdíl není. A na rozdíl od jednoduchého assertu ta výjimka jde dál zpracovat přímo v kódu.

Ale zpět k diskuzi - v C++ výjimky používám nerad, ani ne kvůli výkonu, ale spíš kvůli čitelnosti kódu. Výjimka dost výrazně narušuje tok programu a bez pomoci překladače není jasné, jestli volání nějaké funkce může skončit výjimkou, nebo ne.
Pokud se chyby řeší přes návratové hodnoty, je u jejich použití na první pohled vidět, jestli volající chyby ošetřuje, předává dál, nebo ignoruje. A kdy k tomu dojde. A na rozdíl od výjimek je předávání chyb viditelné v každé funkci, přes kterou chyba prochází. S výjimkami bez podrobnějšího zkoumání nebo hodně přesné dokumentace na první pohled často vůbec není jasné, jestli funkce může selhat a pokud ano, tak s jakými výjimkami. S výjimkami kontrolovanými překladačem, jako to má Java, je situace snesitelná, ale kdo tyhle anotace píše... zvlášť když překladače na ně stejně nereagují.

michalferko> pokud výjimka opravdu nastává tisíckrát za vteřinu, tak je používáš špatně Wink Proto to jsou výjimky, aby byly výjimečné.
_________________
http://trionteam.net
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Krolli



Založen: 12. 05. 2013
Příspěvky: 13

PříspěvekZaslal: 16. červen 2013, 08:15:29    Předmět: Odpovědět s citátem

OndraSej napsal:
Ale zpět k diskuzi - v C++ výjimky používám nerad, ani ne kvůli výkonu, ale spíš kvůli čitelnosti kódu. Výjimka dost výrazně narušuje tok programu a bez pomoci překladače není jasné, jestli volání nějaké funkce může skončit výjimkou, nebo ne.
Pokud se chyby řeší přes návratové hodnoty, je u jejich použití na první pohled vidět, jestli volající chyby ošetřuje, předává dál, nebo ignoruje. A kdy k tomu dojde. A na rozdíl od výjimek je předávání chyb viditelné v každé funkci, přes kterou chyba prochází. S výjimkami bez podrobnějšího zkoumání nebo hodně přesné dokumentace na první pohled často vůbec není jasné, jestli funkce může selhat a pokud ano, tak s jakými výjimkami. S výjimkami kontrolovanými překladačem, jako to má Java, je situace snesitelná, ale kdo tyhle anotace píše... zvlášť když překladače na ně stejně nereagují.


S tymto suhlasim, az na detail ohladom throw anotacie metod/funkcii. Tie anotacie funguju inak ako v Jave a IMHO su nanic. Nekontroluje ich kompilator (nehodi chybu pri preklade ak su nespravne), takze mozu byt out-of-sync s kodom a nikdy nevies, ci si pokryl vsetko (ak nie, popletie to niekoho ineho). Ak tam nejaku vynimku zabudnes uviest a ona vznikne, zavola sa unexpected() a, ak si to nenahradil niecim vlastnym, program spadne. Mozes tam dat throw() (unexpected() pri akejkolvek vynimke) alebo throw(...) (to iste ako keby si tam nedal nic).

Odporucam precitat si A Pragmatic Look at Exception Specifications. Osobne mam ovela radsej navratove hodnoty a zapisovanie do logov. Na druhej strane, raz sa mi stalo, ze mi nejaka metoda hodila UnsupportedException("Multidimensional arrays are supported.") takze sme sa v praci mali na com zabavat. Smile
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Lemik



Založen: 30. 07. 2007
Příspěvky: 138

PříspěvekZaslal: 16. červen 2013, 08:33:24    Předmět: Odpovědět s citátem

Já tedy začínal "až" s C++, takže žádné FILE*, fopen, fread, fprintf apod. a malloc či free leda s tyčí za neprůstřelným sklem - to rád přenechám alokátorům standardní knihovny... Možná to je proč pro mě mají výjimky smysl.

Výjimky vidím _ne_ jako kontrolu, jestli něco bylo správně provedeno - to nekontroluji. Výjimky jsou pro mě příležitostí a místem k řešení situace, ke které by mohlo dojít. Situaci, kvůli které stejně kontrolujete tu vrácenou hodnotu...

A OndraSej to napsal výstižně - pokud potřebuješ chytat výjimku, která může nastat tisíckrát za vteřinu, děláš to špatně...



LukeMak: Z jakého roku to bylo? Přecijenom před 10 - 5 lety to vypadalo jinak, než teď s C++11. Tedy alespoň pro GCC a porty na různé platformy.

Neznám kompilátory pro konzole, takže pokud někdo ví, jak tam jsou řešené - jestli je má vůbec smysl použít - by mě zajímalo. Otázkou je taky, jestli knihovny třetích stran podporu výjimek mají, což s open source nebo licensed source není problém, zkompiluji si to podle svého, horší to bude pokud je k dispozici jen binárka.



Podstatnějším problémem než samotný overhead pak je, jak OndraSej nastínil, problém nedostatečné (self)dokumentace, jaké že to exceptions volaný kód vlastně může vyhodit. U knihoven třetích stran jsem odkázán na "dobrosrdečnost" vývojářů, že to patřičně zmíní v dokumentaci.

Edit:
Á, Krolli to zmínil ještě přede mnou...
Rozhodně nepoužívat u funkcí throw() specifikaci. Ta je v C++11 deprecated. C++11 naopak přidává noexcept (http://www.stroustrup.com/C++11FAQ.html#noexcept a http://en.cppreference.com/w/cpp/language/noexcept)

Nějaké obecné info k výjimkám:
http://www.parashift.com/c++-faq-lite/exceptions.html
http://www.stroustrup.com/bs_faq2.html#exceptions-why

Edit2: opraveny vyjímky na výjimky


Naposledy upravil Lemik dne 19. červen 2013, 09:36:10, celkově upraveno 1 krát
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mar



Založen: 16. 06. 2012
Příspěvky: 602

PříspěvekZaslal: 16. červen 2013, 10:13:39    Předmět: Re: Vyjimky (Exceptions) v hernim prumyslu Odpovědět s citátem

Výjimky v C++ potenciálně můžou vést k resource leakům - překladač totiž při výjimce automaticky uvolní pouze objekty na zásobníku (C++ nemá GC).
Zadalší overhead není ani tak v rychlosti, ale ve velikosti generovaného kódu (resp. dat). Poslední věc: pokud ladím kód, který háže výjimky, tak se najednou můžu ocitnout jinde, než bych čekal (když to vyletí). Já osobně se bez nich obejdu.
OT: Pokud vím, tak někteří vývojáři nepoužívají ani STL (google např. EASTL) a to ani ne z důvodů rychlosti, ale spíš z důvodu opět velikosti kódu - není to problém na PC, ale na konzolích prý většina velkých her běží tak, že mají volných pár MB a jedou doslova nadoraz (aspoň to tvrdil týpek z Ubisoftu Smile
Taky si pamatuji, že hodně lidí rádo předává objekty hodnotou, což má v C++ opět obrovský overhead na velikost kódu a nakonec i rychlost (i když je reference countovaný), nevím, do jaké míry toto do budoucna vylepší překladač/nový standard, ale já zůstávám u const referencí, kde to jde.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
nou



Založen: 28. 07. 2007
Příspěvky: 1047

PříspěvekZaslal: 16. červen 2013, 11:34:16    Předmět: Odpovědět s citátem

ja osobne som vynimkam tiez nikdy neprisiel na chut. nepouzivanie STL je skor relikt minulosti. kontajnery totiz pouzivaju templaty ktorych podpora nebola v minulosti prave najlepsia. za dalsie kvalita implementacie STL bola casto nizka.

neviem ako moze pouzivanie predavanie konstatntov zvysovat velkost kodu. kopirovaci konstruktor by vo vyslednej binarke mal byt iba raz. overhead je pri predavani hodnotou z toho ked sa musia kopirovat velke objekty z jedneho miesta na druhe. to riesi C++11 ktory prinasa move konstruktor na rychle predavanie hodnotou.
_________________
Najjednoduchšie chyby sa najtažšie hľadajú.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mar



Založen: 16. 06. 2012
Příspěvky: 602

PříspěvekZaslal: 16. červen 2013, 12:50:35    Předmět: Odpovědět s citátem

Tak i když je tam konstruktor jednou, volat se musí Smile A destruktor taky. Plus oba potřebují předat this, kopírovací ještě navíc src. Máš pravdu, mrknu se jak je to s move ctorem, docela mě to zajímá (rvalue reference?).
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Vilem Otte



Založen: 18. 09. 2007
Příspěvky: 462
Bydliště: Znojmo - Sedlesovice, Kravi Hora

PříspěvekZaslal: 16. červen 2013, 13:27:14    Předmět: Odpovědět s citátem

#mar - mohu potvrdit tvrzení týpka z Ubisoftu, na konzolích se jede pouze na minimum volné paměti. Mnoho z nich upředností i další varianty typu "tiny-stl".

Nový standard pravděpodobně ponechá klasické předání hodnotou jako kopii celého objektu (tedy alespoň bude-li se držet toho, že je schopen zkompilovat i C), předání referencí či ukazatelem je (a pravděpodobně i bude) stále nejvyužívanější.

#nou - nepoužívání STL je zase s novým standardem jak-kde a jak-na-co. Třeba jejich podpora pro vlákna je dost ubohá u většiny kompilátorů (vše není ještě hotovo, apod.). Příkladem budiž std::thread::hardware_concurrency() - která má vracet počet dostupných hw vláken. Na drtivé většině implementací C++11 vrátí 0 ... super, co?
Jedinou možností pro použití je dnes pravděpodobně boost (kde boost::thread::hardware_concurrency() funguje tak, jak má), nebo si funkce prostě dopsat.

#nou & mar - Kopírovací konstruktor může být inline (resp. jelikož je rozhodnutí na kompilátorů, tak je lepší ho "forcenout" pomocí __forceinline/__attribute__((always_inline))/etc. (compiler specific)), pak je výsledný kód větší.

#OndraSej - Srovnej toto - http://pastebin.com/dKADeYes a http://pastebin.com/BGJ6EgZw, kdy v druhém případě AssertExit funkce mi vše logne (s dalšími detaily), a sama program ukončí.

Samozřejmě někde můžeš vyjímku ošetřit tak že program pokračuje dále, tam taková konstrukce jistý význam může mít - nicméně já jsem úmyslně pro toto jsem vzal příklad z wiki, který vysvětluje jak vyjímky fungují (a většina těch, kteří toto učí použijou stejný příklad) - kde taková konstrukce je useless garbage.

EDIT - tedy v zmíněném AssertExit dle typu vyjímky také provedu její ošetření uvnitř programu. Konstrukcí je také uvnitř "hezčí" než try-catch-finally blok, jelikož se jedná o switch. Co se výkonu týče, můžu přes makro volání odstranit (do release verze).
_________________
Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail Zobrazit autorovi WWW stránky
OndraSej



Založen: 28. 07. 2007
Příspěvky: 765
Bydliště: Brandýs nad Labem

PříspěvekZaslal: 16. červen 2013, 14:36:47    Předmět: Odpovědět s citátem

Vilem Otte> Ne, pořád to jsou jabka s hruškama. Pokud cílem toho assertu je zabít celý program, tak try/catch bloky potřebuješ jenom na top-level (takže jeden na celý program). V kódu ti zbyde jenom to if (...) throw someException. A to klidně můžeš obalit makrem a místo if a throw psát ASSERT_THAT(....), které to zformátuje a přidá název souboru a číslo řádku. Narozdíl od té funkce ale tu výjimku můžeš zpracovat, pokud budeš chtít.

Jinak switch je pěkný, jen dokud se celý vejde na obrazovku (notebooku za 15k), pak už to je dost nepřehledné.

Lemik> ad kompilatory pro konzole - nic o tom nevím, ale celkem bych se vsadil, že pro XBoxy je dostupný MS C++ (resp. něco do Visual Studia) a ostatní mají buď GCC nebo LLVM.
_________________
http://trionteam.net
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
quas4



Založen: 18. 10. 2007
Příspěvky: 199

PříspěvekZaslal: 16. červen 2013, 15:55:26    Předmět: Odpovědět s citátem

nou napsal:
nepouzivanie STL je skor relikt minulosti.


tak to urcite ne. STL je podle me neprehledna hruza. Ve hre kterou ted pisu (STL vubec nepouzivam) mam napriklad napsanou vlastni Map (hashed, s open addressing a linear probing) ktera je rychlejsi (insert i lookup) nez unordered_map. A navic jeji kod je i vyrazne jednodussi a prehlednejsi.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
TeaTime



Založen: 17. 06. 2011
Příspěvky: 264

PříspěvekZaslal: 16. červen 2013, 17:10:57    Předmět: Odpovědět s citátem

quas4 napsal:
nou napsal:
nepouzivanie STL je skor relikt minulosti.


tak to urcite ne. STL je podle me neprehledna hruza. Ve hre kterou ted pisu (STL vubec nepouzivam) mam napriklad napsanou vlastni Map (hashed, s open addressing a linear probing) ktera je rychlejsi (insert i lookup) nez unordered_map. A navic jeji kod je i vyrazne jednodussi a prehlednejsi.


Já si taky občas napíšu nějaký ADT, ale rozhodně bych si nechtěl psát pořád dokola všechno sám. Když zrovna někde potřebuji zásobník a nechce se mi ho hned psát, tak si myslím, že STL nebo boost skvěle plní svou funkci.

Ohledně té rychlosti: je možné, že když si napíšeš datovou strukturu přesně podle svých potřeb, tak dosáhneš vyšší rychlosti než dosáhne obecně navržené STL. Ale celkově jsem měl za to, že ADT v STL je hodně dobře optimalizované.

Ta údajná 'pomalost' unordered_map může být způsobená taky tím, že je to poměrně nový kus kódu. Testování její rychlosti se nedá generalizovat na celé STL.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++ Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2, 3, 4, 5  Další
Strana 1 z 5

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna