Hva slags optimaliseringer gjør alternativet -ffast-math?

Jeg så at tiden det tar for en enkel $ O (n ^ 2) $ -algoritme å bli redusert til en $ O (n) $ -algoritme ved å bruke alternativet.

Kommentarer

  • Jeg tror dette spørsmålet allerede har et svar på Stack Overflow: stackoverflow.com/questions/7420665/…
  • Jeg ' Jeg stemmer for å lukke dette spørsmålet som en duplikat av et spørsmål på en annen SE .
  • @ BillBarth: Å lukke et spørsmål som et duplikat fungerer vanligvis bare innenfor et gitt StackExchange-nettsted, med unntak av åpenbare kryssposter. Se meta.stackexchange.com/questions/172307/… på Meta StackExchange for diskusjon og mulige løsninger.
  • @GeoffOxberry, jeg så det og prøvde en plan B.
  • @BillBarth hvor tror du jeg kunne finne et forseggjort svar?

Svar

Det er et kanonisk svar på dette spørsmålet i GCCs wiki , som er antagelig opprettholdt, er det den klart mest autoritære informasjonskilden for denne typen spørsmål. Dette spørsmålet kan derimot til slutt gå ut på dato. Dette blir forklart mer detaljert i wiki, med eksempler. Det følgende er egentlig et sitat fra den for å illustrere hvordan den svarer på akkurat dette spørsmålet, med mindre kommentarer:

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

    IEEE-standard anbefaler at implementeringer tillater fellehåndterere å håndtere exc tekster som divider med null og overløp. Dette flagget antar at ingen brukssynlig felle vil skje.

  • -funsafe-math-optimizations – Disse optimaliseringene bryter lovene for flytepunktsregning og kan erstatte dem med lovene til vanlig uendelig-presisjonsregning:

    På grunn av avrundingsfeil assosierende lov om algebra trenger ikke holdes fast for flytende punktum, og uttrykk som (x + y) + z er ikke nødvendig lik x + (y + z).

  • -ffinite-math-only – Spesielle mengder som inf eller nan aldri vises, dette sparer tiden du leter etter og håndterer dem på riktig måte. Skal for eksempel $ x – x $ alltid være lik $ 0,0 $?

  • -fno-errno-math

    deaktiverer innstilling av errno-variabelen som kreves av C89 / C99 ved anrop til matematiske bibliotekrutiner. For Fortran er dette standardverdien.

  • -fcx-limited-range

    fører til at rekkevidden for reduksjon av området blir utelatt når du utfører en kompleks inndeling. Dette bruker $ a / b = ((ar * br + ai * bi) / t) + i ((ai * br – ar * bi) / t) $ med $ t = br * br + bi * bi $ og kan fungerer ikke bra på vilkårlige områder for inngangene.

  • -fno-rounding-math

  • -fno-signed-zeros

    På grunn av avrundingsfeil trenger ikke algebras assosierende lov å holde flytende tall og dermed uttrykk som (x + y) + z er ikke nødvendig lik x + (y + z).

Implikasjonene av de to siste er strengt tatt ikke alltid så intuitive som man skulle tro. For eksempel (se wiki), hva med $ – (a – a) = a – a $, er det $ + 0,0 $ eller $ -0,0 $? Jeg tror det er ganske mye litteratur om de nøyaktige implikasjonene, spesielt av Bill Kahan .

  • Ikke direkte nevnt (jeg ser du det ikke?), men med -ffast-math erstattes visse vanlige spesialfunksjoner som den gjensidige $ 1 / x $ og kvadratroten $ \ sqrt {x} $ med mindre presise versjoner som er raskere, men som fremdeles har noen «tålelige» feilnivåer (mot 0ulp-feil som kreves av standarden) – her, for eksempel, er hva presisjon vanligvis blir gitt av glibcs libm . Faktisk er dette den vanligste årsaken til hastighet fra -ffast-math, i kode som gjør mye aritmetikk med divisjoner og kvadratrøtter, nesten til det punktet at jeg ( personlig ) tror de andre undervalgene (-ffinite-math-only og lignende spesielt – signalisering NaN s er ganske nyttige for feilsøking) forårsaker litt også mye bryderi når det gjelder kostnad / nytte.

Jeg så at tiden det tok for en enkel $ O (n ^ 2) $ algoritmen reduseres til en $ O (n) $ -algoritme ved å bruke alternativet.

Jeg tror dette er usannsynlig og det er mulig du har gjort en feil i analysen din.Usikre flytende punktoptimaliseringer kan gjøre individuelle uttrykk noe billigere å evaluere i kraft av å ha et større utvalg av optimaliseringer. Men hastigheten bør alltid være på det meste en konstant faktor. Er det mulig at du sammenlignet en $ O (n ^ 2) $ -algoritme med en $ O (n) $ for utilstrekkelig stor $ n $?

Svar

En $ n ^ 2 $ -algoritme kan reduseres til noe som oppfører seg $ O (n) $ hvis for eksempel $ n $ er kjent for kompilatoren, og er et multiplum av vektorstørrelsen for vektorinstruksjoner (hvis noen) støttet av prosessoren. Hvis kompilatoren kan se alt dette, kan den rulle ut en indre sløyfe og bruke vektorinstruksjoner for å gjøre arbeidet. Dette kan redusere den totale operasjonen som er gjort til en håndfull og forbedre ytelsen vesentlig.

Min lesning er at fast-math ikke muliggjør slik optimalisering, men det kan hvis de implisitt er aktivert av unsafe-math-optimizations på grunn av tilknytningsbegrensninger som er deaktivert der.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *