Wat voor soort optimalisaties doet de optie -ffast-math?

Ik zag dat de tijd die nodig is om een eenvoudig $ O (n ^ 2) $ -algoritme terug te brengen tot die van een $ O (n) $ -algoritme met behulp van de optie.

Opmerkingen

  • Ik denk dat deze vraag al een antwoord heeft op Stack Overflow: stackoverflow.com/questions/7420665/…
  • Ik ' heb gestemd om deze vraag te sluiten als een duplicaat van een vraag op een andere SE .
  • @BillBarth: het sluiten van een vraag als duplicaat werkt over het algemeen alleen binnen een bepaalde StackExchange-site, met uitzondering van voor de hand liggende cross-posts. Zie meta.stackexchange.com/questions/172307/… op Meta StackExchange voor discussie en mogelijke oplossingen.
  • @GeoffOxberry, ik zag dat en probeerde een plan B.
  • @BillBarth waar denk je dat ik een uitgebreid antwoord zou kunnen vinden?

Answer

Er is een canoniek antwoord op deze vraag in de wiki van GCC , namelijk vermoedelijk gehandhaafd, is het verreweg de meest gezaghebbende bron van informatie voor dit soort vragen. Aan de andere kant kan deze vraag uiteindelijk achterhaald raken. Dit wordt allemaal in meer detail uitgelegd in de wiki, met voorbeelden. is in wezen een citaat ervan om te illustreren hoe het deze exacte vraag beantwoordt, met kleine opmerkingen:

  • -fno-signaling-nans
  • -fno-trapping-math

    IEEE-standaard beveelt aan dat implementaties trap-handlers toestaan exc eptions zoals delen door nul en overlopen. Deze vlag gaat ervan uit dat er geen gebruik-zichtbare trap zal plaatsvinden.

  • -funsafe-math-optimizations – Deze optimalisaties overtreden de wetten van de rekenkunde met drijvende komma en kunnen ze vervangen door de wetten van de gewone rekenkunde met oneindige precisie:

    Vanwege afrondingsfouten kan de associatieve wet van algebra hoeft niet te gelden voor getallen met drijvende komma en daarom zijn uitdrukkingen zoals (x + y) + z niet noodzakelijk gelijk aan x + (y + z).

  • -ffinite-math-only – Speciale hoeveelheden zoals inf of nan worden verondersteld nooit te verschijnen, dit bespaart de tijd die nodig is om ernaar te zoeken en ze op de juiste manier af te handelen. Moet $ x – x $ bijvoorbeeld altijd gelijk zijn aan $ 0,0 $?

  • -fno-errno-math

    schakelt het instellen van de errno-variabele uit zoals vereist door C89 / C99 bij het aanroepen van wiskundige bibliotheekroutines. Voor Fortran is dit de standaard.

  • -fcx-limited-range

    zorgt ervoor dat de stap voor het verkleinen van het bereik wordt weggelaten bij het uitvoeren van een complexe deling. Dit gebruikt $ a / b = ((ar * br + ai * bi) / t) + i ((ai * br – ar * bi) / t) $ met $ t = br * br + bi * bi $ en mogelijk werken niet goed op willekeurige bereiken van de invoer.

  • -fno-rounding-math

  • -fno-signed-zeros

    Vanwege afrondingsfouten geldt de associatieve wet van de algebra niet noodzakelijk voor getallen met drijvende komma en dus uitdrukkingen als (x + y) + z zijn niet noodzakelijk gelijk aan x + (y + z).

Strikt genomen zijn de implicaties van de laatste twee niet altijd zo intuïtief als men zou denken. Bijvoorbeeld (zie wiki), hoe zit het met $ – (a – a) = a – a $, is het $ + 0,0 $ of $ -0,0 $? Ik geloof dat er een behoorlijke hoeveelheid literatuur is over de exacte implicaties, vooral door Bill Kahan .

  • Niet direct genoemd (ik zie het niet?), maar met -ffast-math worden bepaalde veelvoorkomende speciale functies zoals de wederkerige $ 1 / x $ en de vierkantswortel $ \ sqrt {x} $ vervangen door less precieze versies die sneller zijn, maar die nog steeds een aantal “aanvaardbare” foutniveaus hebben (versus 0ulp-fout vereist door de standaard) – hier is bijvoorbeeld wat precisie gewoonlijk wordt geboden door glibc “s libm . Dit is inderdaad de meest voorkomende oorzaak van versnelling van -ffast-math, in code die veel rekent met divisies en wortels, bijna tot het punt dat ik ( persoonlijk ) denken dat de andere subopties (-ffinite-math-only en dergelijke vooral – signalering NaN s zijn best handig voor foutopsporing) veroorzaken ook een beetje veel gedoe in termen van kosten / baten.

Ik zag dat de tijd die nodig was voor een simpele $ O (n ^ 2) $ algoritme wordt gereduceerd tot dat van een $ O (n) $ -algoritme met behulp van de optie.

Ik denk dat dit onwaarschijnlijk is en het is mogelijk dat je een fout hebt gemaakt in uw analyse.Onveilige drijvende-komma-optimalisaties kunnen individuele expressies enigszins goedkoper maken om te evalueren omdat ze een grotere keuze aan optimalisaties hebben. Maar de versnelling moet altijd hooguit een constante factor zijn. Is het mogelijk dat u een $ O (n ^ 2) $ -algoritme hebt vergeleken met een $ O (n) $ voor onvoldoende grote $ n $?

Antwoord

Een $ n ^ 2 $ -algoritme kan worden gereduceerd tot iets dat $ O (n) $ gedraagt als, bijvoorbeeld, $ n $ bekend is bij de compiler en een veelvoud is van de vectorgrootte voor de vectorinstructies (indien aanwezig) die door de processor worden ondersteund. Als de compiler dit allemaal kan zien, kan hij een binnenste lus uitrollen en vectorinstructies gebruiken om het werk te doen. Dit kan het totale aantal uitgevoerde bewerkingen tot een handvol verminderen en de prestaties aanzienlijk verbeteren.

Ik heb gelezen dat fast-math dergelijke optimalisatie niet “mogelijk maakt, maar het zou kunnen als ze impliciet zijn ingeschakeld door de unsafe-math-optimizations vanwege associativiteitsbeperkingen die daarin zijn uitgeschakeld.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *