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ául inf vagy nan 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 a NaN 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.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük