Vilken typ av optimeringar gör alternativet -ffast-math?

Jag såg att det tar tid för en enkel $ O (n ^ 2) $ -algoritm att reduceras till en $ O (n) $ -algoritm med hjälp av alternativet.

Kommentarer

  • Jag tror att den här frågan redan har ett svar på Stack Overflow: stackoverflow.com/questions/7420665/…
  • Jag ' Jag röstar för att stänga denna fråga som en duplikat av en fråga på en annan SE .
  • @BillBarth: Att stänga en fråga som ett duplikat fungerar i allmänhet bara inom en given StackExchange-webbplats, med undantag för uppenbara tvärposter. Se meta.stackexchange.com/questions/172307/… på Meta StackExchange för diskussion och möjliga lösningar.
  • @GeoffOxberry, jag såg det och försökte en plan B.
  • @BillBarth var tror du att jag kunde hitta ett detaljerat svar?

Svar

Det finns ett kanoniskt svar på denna fråga i GCCs wiki , vilket är antagligen upprätthålls är det den överlägset mest auktoritativa informationskällan för den här typen av frågor. Denna fråga kan å andra sidan slutligen gå in i tiden. Detta förklaras mer detaljerat i wiki med exempel. Följande är i huvudsak ett citat från det för att illustrera hur det svarar på denna exakta fråga med mindre kommentarer:

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

    IEEE-standarden rekommenderar att implementeringar tillåter fällhanterare att hantera exc texter som dividera med noll och överflöd. Den här flaggan förutsätter att ingen användningssynlig fälla kommer att hända.

  • -funsafe-math-optimizations – Dessa optimeringar bryter lagarna för flytpunktsräkning och kan ersätta dem med lagarna för vanlig oändlig precision aritmetik:

    På grund av avrundningsfel är den associativa lag om algebra behöver inte hållas för flytande punktnummer och uttryck som (x + y) + z är inte nödvändiga lika med x + (y + z).

  • -ffinite-math-only – Speciella mängder som inf eller nan antas att de aldrig dyker upp, detta sparar tid på att leta efter dem och hantera dem på rätt sätt. Ska till exempel $ x – x $ alltid vara lika med $ 0,0 $?

  • -fno-errno-math

    inaktiverar inställningen av errno-variabeln som krävs av C89 / C99 vid anrop till matematiska biblioteksrutiner. För Fortran är detta standard.

  • -fcx-limited-range

    gör att områdesminskningssteget utelämnas vid komplex uppdelning. Detta använder $ a / b = ((ar * br + ai * bi) / t) + i ((ai * br – ar * bi) / t) $ med $ t = br * br + bi * bi $ och kan fungerar inte bra på godtyckliga intervall för ingångarna.

  • -fno-rounding-math

  • -fno-signed-zeros

    På grund av avrundningsfel behöver inte algebras associerande lag behålla flytpunkter och därmed uttryck som (x + y) + z är inte nödvändiga lika med x + (y + z).

Strikt taget är konsekvenserna av de två sista inte alltid så intuitiva som man skulle tro. Till exempel (se wiki), vad sägs om $ – (a – a) = a – a $, är det $ + 0,0 $ eller $ -0,0 $? Jag tror att det finns en hel del litteratur om de exakta konsekvenserna, särskilt av Bill Kahan .

  • Inte direkt nämnt (jag Ser du inte det?), men med -ffast-math ersätts vissa vanliga specialfunktioner som den ömsesidiga $ 1 / x $ och kvadratroten $ \ sqrt {x} $ med mindre exakta versioner som är snabbare, men som fortfarande har vissa ”acceptabla” felnivåer (kontra 0-massfel som krävs enligt standarden) – här är till exempel vilken precision som vanligtvis tillhandahålls av glibcs libm . Det här är faktiskt den vanligaste orsaken till snabbare uppkomst från -ffast-math, i kod som gör mycket aritmetik med delningar och kvadratrötter, nästan till den punkt som jag ( personligen ) tror att de andra underalternativen (-ffinite-math-only och liknande speciellt – signalering NaN är ganska användbara för felsökning) orsakar också lite mycket besvär när det gäller deras kostnad / nytta.

Jag såg att det tog tid för en enkel $ O (n ^ 2) $ algoritmen reduceras till en $ O (n) $ algoritm med alternativet.

Jag tror att detta är osannolikt och det är möjligt att du gjorde ett misstag i din analys.Osäkra optimeringar av flytande punkter kan göra individuella uttryck något billigare att utvärdera på grund av att de har ett större urval av optimeringar. Men hastigheten bör alltid vara högst en konstant faktor. Är det möjligt att du jämförde en $ O (n ^ 2) $ -algoritm med en $ O (n) $ för otillräckligt stor $ n $?

Svar

En $ n ^ 2 $ -algoritm kan reduceras till något som beter sig $ O (n) $ om till exempel $ n $ är känt för kompilatorn och är en multipel av vektorstorleken för vektorinstruktioner (om sådana finns) som stöds av processorn. Om kompilatorn kan se allt detta kan den rulla ut en inre slinga och använda vektorinstruktioner för att utföra arbetet. Detta kan minska den totala verksamheten som görs till en handfull och förbättra prestandan avsevärt.

Min läsning är att fast-math inte möjliggör sådan optimering, men det kan om de implicit är aktiverade av unsafe-math-optimizations på grund av associativitetsbegränsningar som är inaktiverade däri.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *