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, kuten inf tai nan 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 signalointi NaN 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ä.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *