Comparație între float vs overflow cu dublă stivă în limba rusă

TL; DR. float. după cum se aștepta, un dublu este mai rapid. astfel încât dacă lucrați cu cantități mari de date și aveți suficientă floare de precizie. apoi alegeți float. Dacă precizia flotorului nu este suficientă, atunci alegerea dvs. este mică - dublă. Dacă nu aveți nicio pretenție - alegeți ceva, nu veți vedea diferența.







Eu, ca participant la litigiul de mai sus, am decis să scriu un răspuns. Pentru a înțelege ce va fi performanța, am decis să învăț mai întâi un pic de teorie, pentru asta am scris următorul cod:

Pentru care avem următorul asamblator (gcc):

Aceasta nu este întreaga concluzie, dar există suficiente informații. Pentru noi, există două instrucțiuni interesante: addss. addsd - fiecare este o instrucțiune SIMD pentru lucrul cu float (primul) și dublu. Primul gând - trebuie să căutați un manual, poate acolo este scris, care este mai rapid? Acest manual este. dar o scurtă examinare a arătat că nu voi primi un răspuns acolo - judecând după manual aceste instrucțiuni ar trebui să fie executate la fel de repede. Bine. Să lăsăm acest lucru și să încercăm să colectăm codul anterior de la AVX2 în studio, obținem următoarele asm:

Codul nu sa schimbat prea mult, cu excepția faptului că operațiunile au început să se numească vaddsd și vaddss. Nu am intrat în manualul acestor echipe, cred că situația este similară cu cea pe care am văzut-o mai devreme.

Un alt factor important pe care float-ul îl poate avea este impactul său mai mic asupra cache-ului: este jumătate din dimensiune, atunci sarcina din memoria cache va fi mai mică. Astfel, fără a crucifica și a nu picta mai mult, ajungem la următoarea concluzie, care, în general, vine imediat în minte: floatul este mai rapid decât dublul.

Rămâne să verificăm acest lucru în practică, pentru care folosim următorul cod:

Desigur, măsurătorile sunt destul de simple, dar raționamentul este destul de superficială (nu intenționează finalizarea studiului, în acest moment nu am timp pentru el), dar chiar și acest lucru arată că oamenii pretind că implicit ar trebui să fie ales dublu, și că dubla float rapidă - nu sunt bune.







Și încă un test, unde am folosit intrinseca pentru a calcula suma (poate că nu le-am folosit în cel mai bun mod, dar nu știu cum altfel):

Cu acest cod, pe aceeași mașină, obțin un câștig de 2,3-2,5 ori.

Un răspuns bun, dar apare întrebarea. De exemplu, de ce avem o creștere de numai x1,2-1,3, având în vedere că pentru operație putem procesa 8 float și 4 duble. Teoretic, diferența ar trebui să fie x2, dar nu o vedem. Mai mult decât atât, testul meu pentru C # (de asemenea destul de simplu) a arătat o diferență de performanță mai mică de 1%, dar și în favoarea flotorului. Performanța a fost comparată cu operațiuni simple, adică funcțiile care returnează dublu nu sunt utilizate. Această diferență mă conduce la ideea că GCC nu folosește cele mai optime instrucțiuni din motive de a oferi o platformă multiplă. - Mstislav Pavlov 18 ianuarie '16 la 11:24

"De ce câștigăm numai x1.2-1.3, dat fiind faptul că putem procesa 8 flotoare și 4 dublu pentru operațiune?" - @ MstislavPavlov, probabil că aceasta este deja o întrebare pentru mine, deși @ixSci a răspuns practic deja. Uită-te din nou la asm. Există mai multe echipe pentru a lucra cu memoria. În afara memoriei cache, acestea sunt comenzi foarte lente. De fapt, ați calculat nu viteza de adăugare a vectorilor dubli flotați, dar viteza încărcării lor în memoria cache. În răspunsul cu codul ultimul test am făcut-o cu o eroare pentru a arăta influența unui cache asupra rezultatului. - mega 18 ianuarie '16 la 11:48

"Dacă excludeți" greseala "intenționată," diferența va deveni și mai mică, înțeleg corect? " - Numărați-vă: rezultatul penultim este deja fără eroare. Eu doar @avp nu a spus atunci caracteristicile sale pentru RAM. dar a arătat că rezultatele sale sunt mai bune, așa că am făcut ultimul test "dificil". @ixSci poate face același test în ultimul său exemplu. - mega 18 ianuarie '16 la 12:49

Pe baza aceleiași arhitecturi, putem spune că operațiunile cu flotor sunt mai rapide de cel puțin două ori. De exemplu: într-un registru de vectori pe 128 de biți, există 2 duble sau 4 plutitoare. De ce minim - deoarece pregătirea vectorilor poate duce la costuri suplimentare, care vor fi evaluate în același raport. Din limbajul ales, există puțin care depinde, mai probabil - de compilator, de calitatea sa de algoritmi de optimizare pentru utilizarea SSE. - mega 18 ianuarie '16 la 4:47







Articole similare

Trimiteți-le prietenilor: