Millaisia optimointeja vaihtoehto -ffast-math
tekee?
Huomasin, että aika, jonka kuluu yksinkertaisen $ O (n ^ 2) $ -algoritmin vähentämiseen $ O (n) $ -algoritmiin käyttämällä vaihtoehtoa.
Kommentit
- Luulen, että tähän kysymykseen on jo annettu vastaus pinon ylivuotoon: stackoverflow.com/questions/7420665/…
- I ' äänestän tämän kysymyksen sulkemiseksi kopiona kysymyksestä eri SE: ssä .
- @BillBarth: Kysymyksen sulkeminen kopiona toimii yleensä vain tietyllä StackExchange-sivustolla, lukuun ottamatta ilmeisiä ristiviestejä. Katso Meta StackExchangesta meta.stackexchange.com/questions/172307/… keskustelua ja mahdollisia ratkaisuja varten.
- @GeoffOxberry, näin sen ja kokeilin suunnitelmaa B.
- @BillBarth mistä luulen voivani löytää tarkan vastauksen?
Vastaa
Tähän kysymykseen on kanoninen vastaus GCC: n wikissä , joka on oletettavasti ylläpidetty, se on ylivoimaisesti kaikkein arvovaltaisin tietolähde tämäntyyppisissä kysymyksissä. Tämä kysymys voi toisaalta vanhentua. Tämä kaikki selitetään yksityiskohtaisemmin wikissä esimerkkien kera. on lähinnä lainaus siitä, kuinka se vastaa tähän tarkkaan kysymykseen pienillä kommenteilla:
-
-fno-signaling-nans
-
-fno-trapping-math
IEEE-standardi suosittelee, että toteutukset antavat ansakäsittelijöille mahdollisuuden käsitellä esimerkiksi nollalla jakaminen ja ylivuoto. Tämä lippu olettaa, että mitään käyttöä näkyvää ansaa ei tapahdu.
-
-funsafe-math-optimizations
– Nämä optimoinnit rikkovat liukulaskutoimituksen lakeja ja voivat korvata ne tavallisen ääretön tarkkuuden aritmeettisilla laeilla:Pyöristysvirheiden takia assosiatiivinen Algebran lakia ei tarvitse pitää liukulukulukuissa, joten lausekkeet, kuten (x + y) + z, eivät ole välttämättömiä yhtä suuria kuin x + (y + z).
-
-ffinite-math-only
– erityismäärät, kuteninf
tainan
ei koskaan ilmesty, mikä säästää aikaa, joka kuluu niiden etsimiseen ja asianmukaiseen käsittelyyn. Pitäisikö $ x – x $ olla aina yhtä suuri kuin $ 0.0 $? -
-fno-errno-math
poistaa errno-muuttujan asetuksen käytöstä, kuten C89 / C99 vaatii matemaattikirjastorutiinien kutsumisessa. Fortranille tämä on oletusarvo.
-
-fcx-limited-range
aiheuttaa alueen pienennysvaiheen jättämisen pois monimutkaista jakoa suoritettaessa. Tämä käyttää $ a / b = ((ar * br + ai * bi) / t) + i ((ai * br – ar * bi) / t) $ kanssa $ t = br * br + bi * bi $ ja saattaa ei toimi hyvin mielivaltaisilla syötealueilla.
-
-fno-rounding-math
-
-fno-signed-zeros
Pyöristysvirheiden vuoksi algebran assosiatiivinen laki ei ole välttämätön liukuluvut ja siten lausekkeet, kuten (x + y) + z, eivät ole välttämättömiä yhtä suuria kuin x + (y + z).
Kahden viimeksi mainitun seuraukset eivät tarkkaan ottaen ole aina yhtä intuitiivisia kuin luulisi. Esimerkiksi (katso wiki), entä $ – (a – a) = a – a $, onko se $ + 0.0 $ tai $ -0.0 $? Uskon, että tarkkoja seurauksia on melko paljon kirjallisuutta, erityisesti Bill Kahanin käsitteellä.
- Ei mainita suoraan (I etkö näe?), mutta
-ffast-math
-asetuksella tietyt yleiset erikoistoiminnot, kuten vastavuoroinen $ 1 / x $ ja neliöjuuri $ \ sqrt {x} $, korvataan pienemmillä tarkat versiot, jotka ovat nopeampia, mutta joilla on silti joitain ”siedettäviä” virhetasoja (verrattuna standardin edellyttämään 0-massavirheeseen) – tässä esimerkiksi tarkkuus on glibcin libm . Itse asiassa tämä on yleisin syy nopeuttamiseen koodista-ffast-math
koodissa, joka tekee paljon aritmeettista jakoilla ja neliöjuurilla melkein siihen pisteeseen asti, että minä ( henkilökohtaisesti ) luulevat, että muut alavaihtoehdot (-ffinite-math-only
ja vastaavat – etenkin signalointiNaN
s ovat varsin hyödyllisiä virheenkorjauksessa) aiheuttavat hieman paljon vaivaa kustannusten ja hyötyjen suhteen.
Huomasin, että yksinkertaisen $ O (n ^ 2) $: n aika kului algoritmi supistetaan $ O (n) $ -algoritmiksi käyttämällä vaihtoehtoa.
Uskon, että tämä on epätodennäköistä ja on mahdollista, että teit virheen. analyysissasi.Turvalliset liukuluvun optimoinnit saattavat tehdä yksittäisistä lausekkeista jonkin verran halvempia arvioita, koska niiden optimointivalikoima on suurempi. Mutta nopeuden tulisi aina olla korkeintaan vakio. Onko mahdollista verrata $ O (n ^ 2) $ -algoritmia $ O (n) $ -arvoon riittämättömän suurelle $ n $: lle?
Vastaus
$ n ^ 2 $ -algoritmi voidaan supistaa arvoon $ O (n) $ käyttäytyvä, jos esimerkiksi jos kääntäjä tietää $ n $ ja on vektorikoon moninkertainen prosessorin tukemille vektoriohjeille (jos sellaisia on). Jos kääntäjä näkee kaiken tämän, se voi rullata sisemmän silmukan ja käyttää vektorin ohjeita työn suorittamiseen. Tämä voi vähentää suoritettujen toimintojen määrän vain kouralliseksi ja parantaa suorituskykyä huomattavasti.
Luen, että fast-math
ei salli tällaista optimointia, mutta se voisi olla, jos unsafe-math-optimizations
assosiatiivisuusrajoitusten vuoksi, jotka on poistettu käytöstä siellä.