JBlack Skrevet 11. mai 2005 Del Skrevet 11. mai 2005 Ok, her er en oppdatert versjon av et lite program for å teste hvor kjapt det er å bruke forskjellig presisjon på flyttall. Det første programmet hadde en stygg feil, så det glemmer vi. Programmet er inspirert av en diskusjon om flyttall, om C følger en standard (IEEE754) og nysgjerrighet rundt effektiviteten av de forskjellige presisjonene float, double og long double. Se denne tråden: http://forum.hardware.no/index.php?showtopic=410592 Jeg har tatt hensyn til forskjellige tanker rundt det første programmet og optimalisering, fremsatt i denne tråden: http://forum.hardware.no/index.php?showtop...0entry4149492 Jeg passer på at variabelen skrives ut, slik at optimalisering ikke forkaster hele utregningen. Og jeg bruker variabler for konstantene slik at disse er garantert av riktig type når de brukes. Om det siste er viktig, vet jeg ikke. But better safe than sorry. Her er koden: #include <stdio.h> #include <sys/times.h> #include <unistd.h> #define ITERATIONS 10000000 #define ALPHA 3.6 #define START_X 0.4 int main(){ float f; double d; long double l; const float ff=ALPHA; const float f1=1.0; const double df=ALPHA; const double d1=1.0; const long double lf=ALPHA; const long double l1=1.0; long int i; struct tms ts; clock_t t; f=d=l=START_X; printf ("Simple floating point benchmark! Don't take results too seriously!\n\n"); printf ("Does %d iteartions of x=%.2fx(1.0-x), and x0=%.2f\n\n",ITERATIONS,ALPHA,START_X); printf ("Size of float: %d\nSize of double: %d\nSize of long double: %d\n",sizeof(float),sizeof(double),sizeof(long double)); printf ("Ticks per second: %d\n",sysconf(_SC_CLK_TCK)); printf ("ticks must be divided by ticks per second if comparing different platforms.\n\n"); times(&ts); t=ts.tms_utime; for (i=0;i<ITERATIONS;i++){ f=ff*f*(f1-f); } times(&ts); printf("float:\n ticks: %ld\n value: %f\n",ts.tms_utime-t,f); times(&ts); t=ts.tms_utime; for (i=0;i<ITERATIONS;i++){ d=df*d*(d1-d); } times(&ts); printf("double:\n ticks: %ld\n value: %f\n",ts.tms_utime-t,d); times(&ts); t=ts.tms_utime; for (i=0;i<ITERATIONS;i++){ l=lf*l*(l1-l); } times(&ts); printf("long double:\n ticks %ld\n value %Lf\n",ts.tms_utime-t,l); return 0; } Den er testet på AMD64, P4 mobile og Sparc. Resultater følger... Lenke til kommentar
JBlack Skrevet 11. mai 2005 Forfatter Del Skrevet 11. mai 2005 Ok, her er noen resultater: 2.6.11-gentoo-r7 #3 Fri May 6 12:08:24 CEST 2005 x86_64 AMD Athlon 64 Processor 3000+ AuthenticAMD GNU/Linux Size of float: 4 Size of double: 8 Size of long double: 16 Ticks per second: 100 ticks must be divided by ticks per second if comparing different platforms. float: ticks: 9 value: 0.330729 double: ticks: 10 value: 0.426920 long double: ticks 17 value 0.385037 2.6.11-gentoo-r6 #1 Thu Apr 28 17:51:51 CEST 2005 i686 Intel® Pentium® 4 Mobile CPU 2.00GHz GenuineIntel GNU/Linux Size of float: 4 Size of double: 8 Size of long double: 12 Ticks per second: 100 ticks must be divided by ticks per second if comparing different platforms. float: ticks: 17 value: 0.551679 double: ticks: 18 value: 0.403884 long double: ticks 19 value 0.385037 Sparc (ukjent klokkefrekvens, 4CPU'er, server med andre påloggede brukere) SunOS Release 5.9 Version Generic_117171-09 [uNIX® System V Release 4.0] Size of float: 4 Size of double: 8 Size of long double: 16 Ticks per second: 100 ticks must be divided by ticks per second if comparing different platforms. float: ticks: 23 value: 0.330729 double: ticks: 23 value: 0.426920 long double: ticks 950 value 0.382705 Kommentarer: Merk at P4 mobile har 12 bytes (96 bit) på long double. Det tyder på at P4 ikke følger IEEE754 standarden her, men jukser og bruker 80 bits oppløsning i stedet for 128 bit. Fra gammelt av har intel sine prosessorer 80 bits FPU, og tydeligvis støtter ikke disse 128 bit i hardware. Sparc maskina bruker veldig lang tid på long double. Dette tyder på Sparc heller ikke støtter 128 bit FPU presisjon i hardware, men foretar en software emulering av denne. En annen interessant ting er at de forskjellige plattformene gir forskjellige tall som svar. SPARC og AMD64 gir samme verdi for float og double, men P4 gir annen verdi. P4 og AMD64 gir samme verdi på long double, mens SPARC gir en annen. Funksjonen som er brukt har en viss kaotisk oppførsel. Det vil her si at ethvert uendelig lite avvik i startverdi gir en vilkårlig endring i sluttverdien. Det betyr at enhver forskjellig i avrunding eller behandling av tallene, vil gi forskjellig resultat. Så dersom alle plattformene fulgte en gitt standard, så burde alle plattformene gitt eksakt like resultat. Det er tydelig ikke tilfelle. Siden P4 og AMD64 gir samme resultat på long double, så kan man slutte at de har identisk FPU. Dermed kan vi anta at også AMD64 fusker og bruker en 80 bit FPU lik den i P4. Siden P4 avviker fra de to andre når det gjelder float og double, så er det sansynlig at P4 ikke følger noen standard her heller. Om de to andre gjør det er uvisst, ettersom jeg ikke har tilgang til noen fasitt. Vi kan også se at tiden brukt på float og double er omtrent identisk internt på alle plattformene. Dette viser at det er ikke noe å hente ytelsesmessig på å bruke float i forhold til double. Fra double til long double varierer det fra plattform til plattform. AMD64 ser ut til å ha hardware støtte for long double, men via noe ekstra prosessering. Konklusjon: Presisjon på float og double ser ut til å følge IEEE754, men det er likevel forskjeller i utregningsmetode/avrunding. Så noen standard kan man ikke stole på uten videre. P4 og AMD64 fusker når det kommer til long double, og bruker 80bit i stdet for 128bit. Det er ingen ting å hente hastighetsmessig ved bruk av float i forhold til double. Lenke til kommentar
JBlack Skrevet 11. mai 2005 Forfatter Del Skrevet 11. mai 2005 Folk med andre plattformer oppfordres til å bidra. Spesielt de som benytter Mac'er. Lenke til kommentar
phatsam Skrevet 11. mai 2005 Del Skrevet 11. mai 2005 (endret) Size of float: 4 Size of double: 8 Size of long double: 12 Ticks per second: 100 ticks must be divided by ticks per second if comparing different platforms. float: ticks: 14 value: 0.551679 double: ticks: 16 value: 0.403884 long double: ticks 16 value 0.385037 P4 2.4Ghz - 2.6.11-gentoo-r6 , gcc 3.4 Endret 11. mai 2005 av phatsam Lenke til kommentar
A_N_K Skrevet 11. mai 2005 Del Skrevet 11. mai 2005 2.6.11-cko4 #1 Thu Apr 14 18:57:26 CEST 2005 i686 Unknown CPU Typ AuthenticAMD GNU/Linux gcc: Size of float: 4 Size of double: 8 Size of long double: 12 Ticks per second: 100 ticks must be divided by ticks per second if comparing different platforms. float: ticks: 8 value: 0.551679 double: ticks: 8 value: 0.403884 long double: ticks 14 value 0.385037 gcc -O3: float: ticks: 4 value: 0.324037 double: ticks: 5 value: 0.385037 long double: ticks 4 value 0.385037 gcc -O3 -ffast-math: float: ticks: 5 value: 0.410142 double: ticks: 5 value: 0.599849 long double: ticks 6 value 0.599849 Lenke til kommentar
JBlack Skrevet 11. mai 2005 Forfatter Del Skrevet 11. mai 2005 Forskjellige verdier (svar) med og uten -O3. Sikker på at det er riktig? Lenke til kommentar
JBlack Skrevet 11. mai 2005 Forfatter Del Skrevet 11. mai 2005 2.6.8-gentoo-r3 #12 Sun Oct 24 15:39:28 CEST 2004 i686 Intel® Pentium® III Mobile CPU 866MHz GenuineIntel GNU/Linux Size of float: 4 Size of double: 8 Size of long double: 12 Ticks per second: 100 ticks must be divided by ticks per second if comparing different platforms. float: ticks: 20 value: 0.551679 double: ticks: 18 value: 0.403884 long double: ticks 25 value 0.385037 Imponert. Trodde denne gamle greia skulle være mye treigere. Lenke til kommentar
A_N_K Skrevet 11. mai 2005 Del Skrevet 11. mai 2005 Forskjellige verdier (svar) med og uten -O3. Sikker på at det er riktig? Reproduserbart i alle fall. Forresten er prosessoren en AMD XP 2400+ (noe overklokket). Lenke til kommentar
☀ ❄ Skrevet 11. mai 2005 Del Skrevet 11. mai 2005 2.6.9-gentoo-r9 #1 Wed Dec 15 16:12:40 CET 2004 i686 AMD Athlon XP 1500+ AuthenticAMD GNU/Linux float: ticks: 15 value: 0.551679 double: ticks: 15 value: 0.403884 long double: ticks 26 value 0.385037 Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå