Ce fel de optimizări face opțiunea -ffast-math?

Am văzut că timpul necesar unui algoritm simplu $ O (n ^ 2) $ fiind redus la cel al unui algoritm $ O (n) $ utilizând opțiunea.

Comentarii

  • Cred că această întrebare are deja un răspuns pe Stack Overflow: stackoverflow.com/questions/7420665/…
  • Votez ' pentru a închide această întrebare ca duplicat al unei întrebări pe un SE diferit .
  • @ BillBarth: Închiderea unei întrebări ca duplicat funcționează în general numai pe un anumit site StackExchange, cu excepția postărilor încrucișate evidente. Consultați meta.stackexchange.com/questions/172307/… pe Meta StackExchange pentru discuții și soluții posibile.
  • @GeoffOxberry, am văzut asta și am încercat un plan B.
  • @BillBarth unde crezi că aș putea găsi un răspuns elaborat?

Răspuns

Există un răspuns canonic la această întrebare în wiki-ul GCC , care este probabil menținută, este de departe cea mai autoritară sursă de informații pentru acest tip de întrebare. Pe de altă parte, această întrebare poate fi învechită. Toate acestea sunt explicate mai detaliat în wiki, cu exemple. este în esență un citat din acesta pentru a ilustra modul în care răspunde la această întrebare exactă, cu comentarii minore:

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

    Standardul IEEE recomandă ca implementările să permită manipulatorilor de capcane să gestioneze exc. opțiuni precum divizarea la zero și depășirea. Aceste semnalizări presupun că nu se va întâmpla nicio capcană vizibilă pentru utilizare.

  • -funsafe-math-optimizations – Aceste optimizări încalcă legile aritmeticii în virgulă mobilă și le pot înlocui cu legile aritmeticii ordinare de precizie infinită:

    Datorită erorilor de rotunjire, asociativul legea algebrei nu este valabilă pentru numerele cu virgulă mobilă și astfel expresii precum (x + y) + z nu sunt necesare egale cu x + (y + z).

  • -ffinite-math-only – Cantități speciale precum inf sau nan se presupune că nu vor apărea niciodată, astfel se economisește timpul petrecut căutându-i și manipulându-i corespunzător. De exemplu, ar trebui ca $ x – x $ să fie întotdeauna egal cu $ 0.0 $?

  • -fno-errno-math

    dezactivează setarea variabilei errno conform cerințelor C89 / C99 la apelarea rutinelor bibliotecii matematice. Pentru Fortran acesta este valoarea implicită.

  • -fcx-limited-range

    face ca etapa de reducere a intervalului să fie omisă atunci când se efectuează o divizare complexă. Aceasta folosește $ a / b = ((ar * br + ai * bi) / t) + i ((ai * br – ar * bi) / t) $ cu $ t = br * br + bi * bi $ și ar putea nu funcționează bine pe intervale arbitrare de intrări.

  • -fno-rounding-math

  • -fno-signed-zeros

    Datorită erorilor de rotunjire, legea asociativă a algebrei nu este necesară pentru numerele cu virgulă mobilă și astfel expresiile precum (x + y) + z nu sunt necesare egale cu x + (y + z).

Strict vorbind, implicațiile ultimelor două nu sunt întotdeauna atât de intuitive pe cât s-ar putea crede. De exemplu (vezi wiki), ce zici de $ – (a – a) = a – a $, este $ + 0,0 $ sau $ -0,0 $? Cred că există o cantitate destul de mare de literatură cu privire la implicațiile exacte, în special de Bill Kahan .

  • Nu este menționat direct (I nu-l vezi?), dar cu -ffast-math, anumite funcții speciale comune, cum ar fi reciprocul $ 1 / x $ și rădăcina pătrată $ \ sqrt {x} $ sunt înlocuite cu mai puțin versiuni precise, care sunt mai rapide, dar care au încă unele niveluri de eroare „tolerabile” (față de eroarea 0ulp cerută de standard) – aici, de exemplu, este precizia de obicei furnizată de glibc „s libm . Într-adevăr, aceasta este cea mai frecventă cauză de accelerare de la -ffast-math, în cod care face multă aritmetică cu diviziuni și rădăcini pătrate, aproape până la punctul în care eu ( personal ) cred că și celelalte subopțiuni (-ffinite-math-only și altele asemenea – semnalizarea NaN este destul de utilă pentru depanare) cauzează un pic multă bătaie de cap în ceea ce privește costul / beneficiile lor.

Am văzut că timpul necesar unui simplu $ O (n ^ 2) $ algoritmul fiind redus la cel al unui algoritm $ O (n) $ folosind opțiunea.

Cred că acest lucru este improbabil și este posibil să fi făcut o greșeală în analiza dumneavoastră.Optimizările nesigure în virgulă mobilă pot face ca expresiile individuale să fie oarecum mai ieftine de evaluat în virtutea faptului că au o gamă mai largă de optimizări. Dar accelerarea ar trebui să fie întotdeauna cel mult un factor constant. Este posibil să comparați un algoritm $ O (n ^ 2) $ cu un $ O (n) $ pentru $ n $ insuficient de mare?

Răspuns

Un algoritm $ n ^ 2 $ poate fi redus la ceva care se comportă $ O (n) $ dacă, de exemplu, dacă $ n $ este cunoscut de compilator și este un multiplu al dimensiunii vectorului pentru instrucțiunile vectoriale (dacă există) acceptate de procesor. Dacă compilatorul poate vedea toate acestea, poate derula o buclă interioară și poate folosi instrucțiuni vectoriale pentru a face treaba. Acest lucru poate reduce operațiunile generale efectuate la o simplă mână și poate îmbunătăți în mod substanțial performanța.

Citirea mea este că fast-math nu permite o astfel de optimizare, dar ar putea, dacă sunt implicit activate de unsafe-math-optimizations din cauza restricțiilor de asociativitate care sunt dezactivate în acesta.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *