Zobrazit předchozí téma :: Zobrazit následující téma |
Autor |
Zpráva |
mar
Založen: 16. 06. 2012 Příspěvky: 610
|
Zaslal: 24. duben 2015, 02:01:30 Předmět: floaty a optimalizace |
|
|
Po nějaké době jsem narazil opět na něco nečekaného (konkrétně u gcc 4.9.2).
Bavím se o x86 a kódu, co používá legacy FPU (se stackem) a porovnání dvou floatů na rovnost.
Překladač měl hodnotu cachovanou v FPU registru (po nějaké jiné operaci) a porovnával s čerstvě vytaženým floatem.
Problém byl v tom, že hodnota v registru měla interně vyšší přesnost a proto porovnání na selhalo.
Takové agresívní optimalizace pak můžou nadělat spoustu škody.
Vlastně se to netýká přímo C++, totéž se teoreticky může stát i v jakémkoliv JITu.
Nemyslím si ani, že by byl problém přeladače - prostě byly implicitně nastavené agresívní optimalizace
(zkoušel jsem CLion + MinGW a divil jsem se, proč mi testovací projekt běží v release ~100x pomaleji, než v debugu  |
|
Návrat nahoru |
|
 |
Slappy

Založen: 31. 07. 2009 Příspěvky: 169 Bydliště: Zilina
|
Zaslal: 24. duben 2015, 07:25:21 Předmět: |
|
|
Neviem ako vy, ale my sme sa ucili v skole zakladne pravidlo ze floaty (resp. desatinne cisla) sa na rovnost NEPOROVNAVAJU (citujem, vratane velkych pismen).
Pri floatoch sa moze robit len < resp. > a vzdy treba spravit nejaku povolenu odchylku Epsilon. _________________ Skinovane instalatory pre NSIS a Inno Setup, zdarma pre SK/CZ projekty: www.graphical-installer.com |
|
Návrat nahoru |
|
 |
Radis
Založen: 29. 03. 2014 Příspěvky: 235
|
Zaslal: 24. duben 2015, 07:48:32 Předmět: |
|
|
No jasne, taky maruv prispevek nejak nechapu. Ty jako porovnavas floaty pomoci ==, a kdyz ti to nefunguje, tak je to podle tebe kvuli agresivnim optimalizacim? To snad ne.
Tohle je snad jedna z prvnich programatorskych lekci...
kód: |
float x = 0.1;
if (x * 6 == 0.6) {
printf("surprise!");
}
|
Ale mozna jsme te se slappym jen spatne pochopili, muzes to nejak dovysvetlit?  |
|
Návrat nahoru |
|
 |
micky

Založen: 28. 02. 2008 Příspěvky: 348 Bydliště: Plzeň, Praha
|
Zaslal: 24. duben 2015, 07:54:30 Předmět: |
|
|
Nám to říkali taky...
Když už je to tady... Floaty jsou vůbec velká legrace, nevíte někdo něco o tom, jestli ten standard definuje i deterministický výpočet? Jestli dva stroje spočtou stejný výsledek při běhu stejného programu, co je nastavený /fp:strict... Nikde jsem nenašel kloudnou odpověď, všichni říkají "no asi ne" a "spočte to co nejpřesněji může".
Řeším to třeba kvůli multiplayeru/replayi, jak moc se na takové floaty spolehnout. Máme v týmu i radikála, který prohlásil, že do herních stavů by floaty vůbec nedával a pozice řešil celočíselně nebo přes fixed-point. _________________ https://www.bluepulsar.cz/
https://twitter.com/11thDream_Game/ |
|
Návrat nahoru |
|
 |
mar
Založen: 16. 06. 2012 Příspěvky: 610
|
Zaslal: 24. duben 2015, 09:32:14 Předmět: |
|
|
slappy: samozřejmě máš pravdu, jistota je kulomet
pointa je ta, že tento typ optimalizací je velmi nebezpečný. Pokud pominu nekonzistenci (pokud přidám pár FPU operací, tak porovnání projde,
nemluvě o tom, že to může rozbít pečlivě navržené numerické výpočty, které vyžadují konzistenci.
radis: opět jsi naprosto nepochopil, o čem mluvím (proč mě to nepřekvapuje ale tak hlavně, že rozdáváš lekce
kód: |
func(Vec3 u)
{
u.Normalize();
// never triggers
if ( u == cached ) {
return;
}
cached = u;
// ... something expensive ...
}
|
micky: pokud máš /fp:strict, máš zaručenou konzistenci a nemusíš se bát
EDIT: pro zaručení přenositelnosti by ti měl stačit defaultní fp:precise
Naposledy upravil mar dne 24. duben 2015, 12:44:35, celkově upraveno 1 krát |
|
Návrat nahoru |
|
 |
Radis
Založen: 29. 03. 2014 Příspěvky: 235
|
Zaslal: 24. duben 2015, 10:45:12 Předmět: |
|
|
mar: Jasne. Moje lekce je: Mile deti, takhle dopadnete, kdyz nebudete ve skole davat pozor a budete porovnavat floaty. Pak budete psat na fora neco o agresivnich optimalizacich  |
|
Návrat nahoru |
|
 |
pcmaster

Založen: 28. 07. 2007 Příspěvky: 1827
|
Zaslal: 24. duben 2015, 12:47:29 Předmět: |
|
|
Podla mna je otazka na "standard" a deterministicky vypocet v kontexte "programu" s "/fp:strict" divna.
Jednotlive INSTRUKCIE s floatami (alebo s cimkolvek) su samozrejme deterministicke a vysledky su vzdy konzistentne.
Optimalizujuci prekladac ale moze operacie preusporiadat a pozmenit tak, ako to uzna za vhodne (podla nejakych nastaveni) a kazdemu je jasne, ze floatove operacie su zavisle na poradi -> vysledky budu rozne.
Ak sa bavime o hrach, tak sa floaty nikdy priamo neporovnavaju -> je nam to jedno (ci sa vertex vykresli na pozicii o 0.001 m vedla alebo farba bude o 0.002 jasnejsia)  _________________ Off-topic flame-war addict since the very beginning. Registered since Oct. 2003!
Interproductum fimi omne est. |
|
Návrat nahoru |
|
 |
micky

Založen: 28. 02. 2008 Příspěvky: 348 Bydliště: Plzeň, Praha
|
Zaslal: 24. duben 2015, 13:34:33 Předmět: |
|
|
To jo, v grafice to fakt většinou jedno je, leda by to s sebou neslo nějaké artefakty.
Spíš mi jde o herní stav, kdy kvůli drobné odchylce se pak sepne nějaký trigger a všechno od té chvíle bude probíhat už velmi odlišně. Jen jsem natrefil na zvěsti, že program nemusí vyjít stejně na AMD a Intelu, tak jsem to předhodil zdejším lvům, jestli o tom něco neví... tady totiž ví všechno  _________________ https://www.bluepulsar.cz/
https://twitter.com/11thDream_Game/ |
|
Návrat nahoru |
|
 |
frca

Založen: 28. 07. 2007 Příspěvky: 1561
|
Zaslal: 24. duben 2015, 13:50:38 Předmět: |
|
|
V MinGW je bug, kdy identický kód dává jiné výsledky na FPU a SSE. Je to dané ořezáním přesnosti (některé operace a mezivýsledky se provádějí ve větší přesnosti, než jsou pak výsledky). Je to starý bug, ale nikdo pořádně neví, jak ho rozumně řešit, tak je tam furt. Teď ho nemůžu najít, ale někde v jejich trackeru je. Možná ten tvůj problém s tím souvisí. Řešení je vykašlat se na FPU a používat SSE, které je navíc rychlejší. _________________ www.FRANTICWARE.com |
|
Návrat nahoru |
|
 |
mar
Založen: 16. 06. 2012 Příspěvky: 610
|
Zaslal: 24. duben 2015, 15:58:42 Předmět: |
|
|
frca: ano, to je přesně ten případ (z mého pohledu ale spíš featura, tj. nebezpečná optimalizace).
SSE jsem původně taky očekával, ale disassembly bylo proti
Nicméně jsem to v tomto případě "vyřešil" pomocí epsilonu, každopádně z mého pohledu bych byl rád, kdyby toto nekonzistentní chování nebylo defaultně zapnuté (ale od toho jsou compiler switche).
Co se týká rendereru, jak psal micky - tam je ti to opravdu jedno, desetinné místo sem nebo tam, who cares dokud to vypadá rozumně.
Ale jsou i jiné oblasti (třeba DT/convex hull), kde je potřeba mít robustní geometrické predikáty (pokud se chceš vyhnout perturbaci), abys dostal správný výsledek ve 100% případů,
ne jen v 99% jako s ne tak úplně všespásným epsilonem (a zároveň srovnatelně rychle).
Pro Shewchukovy expansions (=n floatů s posunutými exponenty, jejijchž virtuální suma dává exaktní výsledek) je naprosto kritické, aby mezivýpočty měly předem danou přesnost a chování (rounding) a bylo možné počítat s danou chybou
(a aby fungoval adaptivní výpočet). |
|
Návrat nahoru |
|
 |
Vilem Otte

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

Založen: 28. 02. 2008 Příspěvky: 348 Bydliště: Plzeň, Praha
|
|
Návrat nahoru |
|
 |
]semo[

Založen: 29. 07. 2007 Příspěvky: 1526 Bydliště: Telč
|
Zaslal: 27. duben 2015, 09:38:27 Předmět: |
|
|
K tomu porovnávání floatů bez epsilonu: někdy se to hodí. Co třeba tohle?
kód: |
float x = INVALID_VALUE;
MoznaZmenX(&x);
if (x == INVALID_VALUE)
...zmenilo se |
Neříkám, že to nejde udělat jinak, ale už jsem něco podobného někdy použil.
Může to selhat kvůli tomu, co psal mar? _________________ Kdo jede na tygru, nesmí sesednout.
---
http://www.inventurakrajiny.cz/sipka/
Aquadelic GT, Mafia II, simulátory |
|
Návrat nahoru |
|
 |
frca

Založen: 28. 07. 2007 Příspěvky: 1561
|
Zaslal: 27. duben 2015, 10:20:23 Předmět: |
|
|
Ne, toto neselže. Teda pokud INVALID_VALUE není NaN  _________________ www.FRANTICWARE.com |
|
Návrat nahoru |
|
 |
]semo[

Založen: 29. 07. 2007 Příspěvky: 1526 Bydliště: Telč
|
Zaslal: 27. duben 2015, 10:22:27 Předmět: |
|
|
:-D jasně
assert((INVALID_VALUE == INVALID_VALUE) && "don't use NaN"); _________________ Kdo jede na tygru, nesmí sesednout.
---
http://www.inventurakrajiny.cz/sipka/
Aquadelic GT, Mafia II, simulátory |
|
Návrat nahoru |
|
 |
|