Hvilken slags optimeringer gør indstillingen -ffast-math?

Jeg så, at det tager tid for en simpel $ O (n ^ 2) $ -algoritme at blive reduceret til en $ O (n) $ -algoritme ved hjælp af indstillingen.

Kommentarer

  • Jeg tror, dette spørgsmål allerede har et svar på Stack Overflow: stackoverflow.com/questions/7420665/…
  • I ' m stemmer for at lukke dette spørgsmål som en duplikat af et spørgsmål om en anden SE .
  • @BillBarth: At lukke et spørgsmål som en duplikat fungerer normalt kun inden for et givet StackExchange-websted med undtagelse af åbenlyse krydsindlæg. Se meta.stackexchange.com/questions/172307/… på Meta StackExchange for diskussion og mulige løsninger.
  • @GeoffOxberry, jeg så det og prøvede en plan B.
  • @BillBarth hvor tror du, jeg kunne finde et udførligt svar?

Svar

Der er et kanonisk svar på dette spørgsmål i GCCs wiki , hvilket er formodentlig vedligeholdt, er det langt den mest autoritative informationskilde til denne type spørgsmål. Dette spørgsmål kan på den anden side muligvis gå ud på dato. Dette forklares mere detaljeret i wiki med eksempler. Det følgende er i det væsentlige et citat fra det for at illustrere, hvordan det svarer på dette nøjagtige spørgsmål med mindre kommentarer:

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

    IEEE-standard anbefaler, at implementeringer tillader fældehåndterere at håndtere exc tekster som divider med nul og overløb. Dette flag antager, at der ikke sker nogen synlig brugsfælde.

  • -funsafe-math-optimizations – Disse optimeringer bryder lovene for flydende-aritmetik og kan erstatte dem med lovene for almindelig uendelig-præcision-aritmetik:

    På grund af afrundingsfejl er den associative lov om algebra behøver ikke at holde til flydende tal, og udtryk som (x + y) + z er ikke nødvendige lig med x + (y + z).

  • -ffinite-math-only – Særlige mængder såsom inf eller nan antages aldrig at dukke op, det sparer tid brugt på at lede efter dem og håndtere dem korrekt. Skal for eksempel $ x – x $ altid være lig med $ 0,0 $?

  • -fno-errno-math

    deaktiverer indstilling af errno-variablen som krævet af C89 / C99 ved opkald til matematiske biblioteksrutiner. For Fortran er dette standard.

  • -fcx-limited-range

    får rækkevidde til reduktion af rækkevidde, når der udføres kompleks opdeling. Dette bruger $ a / b = ((ar * br + ai * bi) / t) + i ((ai * br – ar * bi) / t) $ med $ t = br * br + bi * bi $ og kan fungerer ikke godt på vilkårlige intervaller for input.

  • -fno-rounding-math

  • -fno-signed-zeros

    På grund af afrundingsfejl behøver algebras associerende lov ikke at være flydende tal og således er udtryk som (x + y) + z ikke nødvendige lig med x + (y + z).

Implikationer af de sidste to er strengt taget ikke altid så intuitive som man måske tror. For eksempel (se wiki), hvad med $ – (a – a) = a – en $, er det $ + 0,0 $ eller $ -0,0 $? Jeg mener, at der er en hel del litteratur om de nøjagtige implikationer, især af Bill Kahan .

  • Ikke direkte nævnt (I kan du ikke se det?), men med -ffast-math erstattes visse almindelige specialfunktioner såsom den gensidige $ 1 / x $ og kvadratroden $ \ sqrt {x} $ med mindre præcise versioner, der er hurtigere, men som stadig har nogle “tålelige” fejlniveauer (versus 0ulp-fejl krævet af standarden) – her er for eksempel, hvad præcision normalt leveres af glibcs libm . Dette er faktisk den mest almindelige årsag til hastighed fra -ffast-math, i kode, der gør en masse aritmetik med divisioner og kvadratrødder, næsten til det punkt, at jeg ( personligt ) synes de andre underoptioner (-ffinite-math-only og lignende især – signalering NaN s er ret nyttige til debugging) forårsager også lidt meget besvær med hensyn til deres omkostninger / fordel.

Jeg så, at det tog tid for en simpel $ O (n ^ 2) $ algoritme reduceres til en $ O (n) $ algoritme ved hjælp af indstillingen.

Jeg mener, det er usandsynligt, og det er muligt, at du har lavet en fejl i din analyse.Usikre floating-point-optimeringer kan gøre individuelle udtryk noget billigere at evaluere i kraft af at have et større udvalg af optimeringer. Men hastigheden skal altid være højst en konstant faktor. Er det muligt, at du sammenlignede en $ O (n ^ 2) $ -algoritme med en $ O (n) $ for utilstrækkelig stor $ n $?

Svar

En $ n ^ 2 $ -algoritme kan reduceres til noget, der opfører sig $ O (n) $, hvis f.eks. $ n $ er kendt af kompilatoren og er et multiplum af vektorstørrelsen til vektorinstruktioner (hvis nogen) understøttet af processoren. Hvis kompilatoren kan se alt dette, kan den rulle en indre sløjfe og bruge vektorinstruktioner til at udføre arbejdet. Dette kan reducere de samlede operationer udført til en håndfuld og forbedre præstationen betydeligt.

Min læsning er, at fast-math ikke muliggør en sådan optimering, men det kunne, hvis de implicit er aktiveret af unsafe-math-optimizations på grund af tilknytningsbegrænsninger, der er deaktiveret deri.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *