.[ ČeskéHry.cz ].
ako sa vyhnut nan, inf, atd

 
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
kerekes



Založen: 29. 07. 2007
Příspěvky: 57

PříspěvekZaslal: 11. duben 2012, 13:12:37    Předmět: ako sa vyhnut nan, inf, atd Odpovědět s citátem

Zdravim
chcel by som sa spytat, ako v kode osetrujete situacie, ked za urcitych podmienok moze vzniknut nan/inf.

Napriklad casto sa v grafike riesi vec ze dot product dvoch normalizovanych vektorov sa posiela do acos funkcie (ktora ocakava rozsah <-1, 1>). Lenze pri poctoch casto nastane pripad, ze nasobenim/spocitavanim a pod dostanem napr aj 1.00000001 co skonci nanom. Ten sa dalej presuva a scasu nacas moze coto v scene rozbit - nehovoriac o tom ze predpokladam to bude mat aj dopad na vykon ak sa v pipeline vyskytne cosi take. Tieto operacie casto idu vo velkom mnozstve (napr pocitanie kolizii).

Druhy priklad je ze vam z nejakeho dovodu pri nejakych vypoctoch na geometrii v urcitych situaciach vyde delenie 0. Ono by to ani nevadilo ak by vysledok bol len nejake velke cislo, ktore je porovnatelne, resp ktore sa da nasobit 0 a pod. Lenze ked sa uz raz vyskytne take cosi tak sa divne spravaju aj porovnania a opat to rozhodi cosi v scene.

Takze otazka je ako sa s tym efektivne popasovat?

Myslim, ze nieje dobry napad (nefektivne) pred kazdym casovo kritickym volanim acosf() davat nieco ako clampovanie na hodnotu v rozsahu -1 ,1 cez nejake dvojice ifov a pod.

Je nejaka funkcia ktora vie velmi rychlo zistit/porovnat vyskyt akehokolvek nan/inf (qnan, snan, ...) v premennej aby som mohol trebarz napriklad skipnut vypocet kolizie na danom trojholniku?

Diki
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
rezna



Založen: 27. 07. 2007
Příspěvky: 2156

PříspěvekZaslal: 11. duben 2012, 15:21:13    Předmět: Odpovědět s citátem

_isnan() ?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
pcmaster



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

PříspěvekZaslal: 11. duben 2012, 15:29:28    Předmět: Odpovědět s citátem

Bojim sa, ze clampovat to rucne akymkolvek sposobom pred poslanim do funkcie, ktora ocakava nejaky rozsah JE to prave a jedine riesenie. Ak mas niekde delenie a vies, ze ti menovatel moze byt niekedy byt 0, musis to osetrit podmienkou. Alebo davat do odmocniny alebo logaritmu zaporne cisla... Jednoducho to musis detegovat. A najlepsie este predtym, nez ti z toho NaN vylezie.
_________________
Off-topic flame-war addict since the very beginning. Registered since Oct. 2003!
Interproductum fimi omne est.
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: 11. duben 2012, 16:08:49    Předmět: Odpovědět s citátem

Testovat isnan má částečně smysl, nicméně to může dramaticky zpomalit program (zvláště pokud je funkce volána mnohokrát při každém cyklu programu.

Co je lepší je zvládnout napsat kód tak, ať umí pracovat s těmito hodnotami Wink (dříve na ompf.org (než stránka "umřela") jsme měli několik témat ohledně zvládání nan v kódu - možná zkusit prohledat google cache) - e.g. používat min/max (na SSE, ne if-ovou verzi, ta je hrozně pomalá) na clamping hodnot. Rozumně předpočítat 1/value tak, že to clampneš do nějakých rozumných hodnot a poté tím násobit, raději než všude dělit, atd.

EDIT: btw. proč volat acos funkci, raději použij taylorův rozvoj - usnadní ti to práci s hodnotami o chlup mimo (viz. acos(1.0000001f) například), a pokud použiješ dost členů, bude to i přesnější Wink
_________________
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
Ladis



Založen: 18. 09. 2007
Příspěvky: 1536
Bydliště: u Prahy

PříspěvekZaslal: 11. duben 2012, 17:58:29    Předmět: Odpovědět s citátem

pcmaster napsal:
Ak mas niekde delenie a vies, ze ti menovatel moze byt niekedy byt 0, musis to osetrit podmienkou.

Dopadu na výkon té kontroly na nulu apod. se bát tolik nemusíte. Před pár dny jsem si četl několikastránkové PDF o CPU 486, a už tam pokračoval ve zpracování kódu v pipeline pro případ "podmínka nesplněna" a nezdržoval se. Novější CPU to zvládaj pro oba případy podmínky (už Pentium 4 odhadovalo podmínku >90 % případů, konkurenční Athlon zas v klidu počítal obě větvě, a pak jednu zahodil - přecijen váš kód obvykle nevytíží všechny výpočetní jednotky jádra CPU).
_________________
Award-winning game developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
VladR



Založen: 30. 07. 2007
Příspěvky: 1322
Bydliště: Greater New York City Area

PříspěvekZaslal: 11. duben 2012, 19:37:10    Předmět: Odpovědět s citátem

To je samozrejme pravda, len clovek ma proste taky hkupy pocit, ked ten kod zasvini tou dodatocnou podmienkou, ktora na prvy pohlad vyzera, ze kod poriadne spomali, obzvlast ak je tam nejaky vypocet na riadok/dva a zrazu tam drbnes dvojriadkovu podmienku.

V reale, samozrejme, je dopad temer nulovy, kedze tie vetvy su na dnesnych CPU spracovane paralelne.

Pokial si clovek da pozor na Pointer Aliasing a v tej podmienke nedereferencuje, tak nedojde ani len k trashnutiu cache.

Druha vec je, ak by ta podmienka zrusila paralelizmus pod SSE, ale v beznom C++ kode to problem robit nebude.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 11. duben 2012, 22:03:53    Předmět: Odpovědět s citátem

Na gcc existují makra likely a unlikely, které se používají v podmínce třeba takhle:
kód:
if (unlikely(x > 1)) { ... }

gcc to pak přeloží tak, aby to CPU líp vyhovovalo, a zároveň této informace využívá při vlastních optimalizacích.

Jinak clamping jsem vždycky dělal a nikdy jsem s tím neměl problém. O výkon této operace jsem se nestaral, protože to pro mě nebylo úzké místo.
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
kerekes



Založen: 29. 07. 2007
Příspěvky: 57

PříspěvekZaslal: 12. duben 2012, 07:29:10    Předmět: Odpovědět s citátem

Dik za odpovede,
asi nezostava nic ine nez to clampovat/davat podmienky.

Ohladom toho vetvenia, vraj to dost spomaluje (teda minimalne na ps3), napr ako pise jeden clovek tuna (na priklade particle systemu):

http://overbyte.com.au/2011/11/10/optimisation-lesson-2/

Ako aby sme sa chapali, viem ze optimalizovat ma zmysel az ked sa zisti ze ten kus kodu naozaj spomaluje, ja len sa snazim najst dopredu efektivny sposob ako sa vyhnut nanom.

Vilem Otte: kolko clenov taylorovho rozvoja da rozumny vysledok porovnatelny s acosf (presnostou aj rychlostou)?

Diki
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
nou



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

PříspěvekZaslal: 12. duben 2012, 09:13:17    Předmět: Odpovědět s citátem

z wiki pre sin(x) s rozvojom na 4 cleny
citace:
The error in this approximation is no more than |x|9/9!. In particular, for ?1 < x < 1, the error is less than 0.000003.
takze pre float by som to videl ako dostatocnu presnost.
_________________
Najjednoduchšie chyby sa najtažšie hľadajú.


Naposledy upravil nou dne 12. duben 2012, 09:30:41, celkově upraveno 1 krát
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: 12. duben 2012, 09:30:15    Předmět: Odpovědět s citátem

Rozdíl mezi větvením (pomalé) a clampingem je opravdu značný.

Uvedu příklad - ray-aabb test, v prvním případě standardní větvící test (používá jej např. luxrender): http://pastebin.com/8Xvr9Jfz

Oproti full SSE packet testu (který je 2.2 - 3.4x rychlejší, jenže zpracuje rovnou 4 rays vs. 1 aabb) je mnohem pomalejší - full packet ray-aabb test http://pastebin.com/fMnQDAEq

Tedy dokud lze použít clamping a vyhnout se větvení, použij clamping Wink

Pozn. pro rýpaly - ten packet test bude rychlejší i pokud do něj dáte pouze jedinou polopřímku Wink
_________________
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
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
Strana 1 z 1

 
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