Milyen optimalizálásokat végez a -ffast-math
opció?
Láttam, hogy a egy egyszerű $ O (n ^ 2) $ algoritmus idejének csökkentése egy $ O (n) $ algoritmuséra az opció használatával.
Megjegyzések
- Azt hiszem, erre a kérdésre már van válasz a verem túlcsordulásával kapcsolatban: stackoverflow.com/questions/7420665/…
- Én ' szavazok, hogy lezárjam ezt a kérdést, mint egy kérdés másolatát egy másik SE-n .
- @BillBarth: A kérdés duplikátumként történő bezárása általában csak egy adott StackExchange webhelyen működik, a nyilvánvaló keresztbejegyzések kivételével. Lásd: meta.stackexchange.com/questions/172307/… a Meta StackExchange webhelyen, ahol megbeszélést és lehetséges megoldásokat találhat.
- @GeoffOxberry, ezt láttam és kipróbáltam egy B tervet.
- @BillBarth, szerinted hol találnék kidolgozott választ?
Válasz
Erre a kérdésre kanonikus válasz van a GCC wikijében , amely: feltehetően fenntartva, ez messze a leghitelesebb információforrás az ilyen típusú kérdésekhez. Ez a kérdés viszont végül elavulhat. Mindezt részletesebben a wiki, példákkal magyarázza. lényegében egy idézet annak illusztrálására, hogy miként válaszol erre a kérdésre, apróbb megjegyzésekkel:
-
-fno-signaling-nans
-
-fno-trapping-math
Az IEEE szabvány azt javasolja, hogy a megvalósítások engedélyezzék a csapdakezelőknek az exc Az olyan opciók, mint nulla osztása és túlcsordulás. Ez a jelző feltételezi, hogy nem történik használatra látható csapda.
-
-funsafe-math-optimizations
– Ezek az optimalizálások megsértik a lebegőpontos aritmetika törvényeit, és felválthatják azokat a közönséges végtelen pontosságú számtan törvényeivel:A kerekítési hibák miatt az asszociatív Az algebra törvénye nem szükséges a lebegőpontos számok esetében, így az (x + y) + z kifejezések nem szükségesek, egyenlőek az x + (y + z) értékkel.
-
-ffinite-math-only
– Különleges mennyiségek, példáulinf
vagynan
soha nem jelenik meg, ez megspórolja a keresésre és a megfelelő kezelésre fordított időt. Például a $ x – x $ értéknek mindig meg kell egyeznie a $ 0.0 $ értékkel? -
-fno-errno-math
letiltja az errno változó beállítását, amint azt a C89 / C99 előírja a matematikai könyvtár rutinok hívásakor. A Fortran esetében ez az alapértelmezett.
-
-fcx-limited-range
a tartománycsökkentési lépés kihagyását eredményezi a komplex osztás végrehajtásakor. Ez a $ a / b = ((ar * br + ai * bi) / t) + i ((ai * br – ar * bi) / t) $ értéket használja a $ t = br * br + bi * bi $ értékkel, és nem működik jól a bemenetek tetszőleges tartományain.
-
-fno-rounding-math
-
-fno-signed-zeros
Kerekítési hibák miatt az algebra asszociatív törvénye nem szükséges lebegőpontos számok, így az (x + y) + z kifejezések nem szükségesek, egyenlőek az x + (y + z) értékkel.
Szigorúan véve az utóbbi kettő következményei nem mindig olyan intuitívak, mint gondolnánk. Például (lásd wiki), mi a helyzet a $ – (a – a) = a – a $ -val, ez $ + 0,0 $ vagy $ -0,0 $? Úgy gondolom, hogy van egy csomó irodalom a pontos következményekről, különösen Bill Kahan részéről.
- Közvetlenül nem említik (I nem látja?), de a
-ffast-math
funkcióval bizonyos általános funkciók, például a kölcsönös $ 1 / x $ és a négyzetgyök $ $ sqrt {x} $ helyett kevesebb precízebb verziók, amelyek gyorsabbak, de amelyeknek még mindig van néhány “tolerálható” hibaszintje (szemben a szabvány által előírt 0ulp hibával) – itt például az a pontosság, amelyet a glibc libm . Valóban, ez a leggyakoribb oka a felgyorsításnak-ffast-math
-től olyan kódban, amely sok aritmetikát végez osztásokkal és négyzetgyökkel, szinte addig a pontig, hogy én ( személyesen ) úgy gondolja, hogy a többi alopció (-ffinite-math-only
és hasonlók – főleg aNaN
jelzései nagyon hasznosak a hibakereséshez) is okoznak egy kicsit sok gondot jelent a költség / haszon szempontjából.
Úgy láttam, hogy egy egyszerű $ O (n ^ 2) $ -hoz szükséges idő az algoritmus egy opció segítségével egy $ O (n) $ algoritmusra csökken.
Úgy gondolom, hogy ez valószínűtlen, és lehetséges, hogy hibát követett el elemzésében.A nem biztonságos lebegőpontos optimalizálás az egyéni kifejezéseket valamivel olcsóbbá teheti az optimalizálás nagyobb választékának köszönhetően. De a gyorsulásnak mindig legfeljebb állandó tényezőnek kell lennie. Lehetséges, hogy összehasonlítottál egy $ O (n ^ 2) $ algoritmust egy $ O (n) $ -val az elégtelen nagy $ n $ -hoz?
Válasz
Egy $ n ^ 2 $ algoritmust lecsökkenthetünk valamire, amely $ O (n) $ viselkedést mutat, ha például ha $ n $ ismeretes a fordító számára, és a vektorméret többszöröse a processzor által támogatott vektoros utasításokhoz (ha vannak ilyenek). Ha a fordító mindezt látja, akkor feltekerhet egy belső hurkot, és vektoros utasítások segítségével végezheti el a munkát. Ez az elvégzett műveleteket csak néhányra csökkentheti, és jelentősen javíthatja a teljesítményt.
Olvastam, hogy a fast-math
nem engedélyezi az ilyen optimalizálást, de igen, ha a unsafe-math-optimizations
az ott letiltott asszociativitási korlátozások miatt.