2014-06-30 8 views
5

Ich versuche, Berechnungszeiten eines einfachen Codes zu vergleichen, um die Summe von Cubes von ganzen Zahlen zu berechnen, die Fortran 90 und C++ verwenden, seit ich gehört hatte, dass sie auf ähnlichen Niveaus schnell sind. Ich verwende gfortran und g ++ (auf Mac OSX), um diese Codes zu kompilieren.Wie kann ich diesen einfachen Fortran 90 Code schneller machen?

Kann jemand freundlich darauf hinweisen, warum der Fortran 90 Code so viel mehr Zeit benötigt (49 Sekunden) als sein entsprechender C++ Code (12 Sekunden)? Nur, dass ich weiß, dass C++ Zeilenmajor ist und Fortran die Hauptspalte ist, aber ich denke nicht, dass das für diese Codes relevant ist. Wie kann ich diesen Fortran90 Code schneller machen? Irgendwelche Tipps werden geschätzt. Vielen Dank.

Fortran-Code und die Zusammenstellung mit gfortran -o bb1 code15.f90

program code15 
implicit none 

double precision, dimension(:), allocatable :: a 
integer (kind=8) :: n,i 
real (kind=16) :: ssum 
real :: ts1, ts2 

call cpu_time(ts1) 
n = 1600000000 
allocate(a(n)) 
ssum=0.0 

do i=1,n 
    a(i)=i 
    ssum=ssum+a(i)*a(i)*a(i) 
end do 

print *, 'final sum ', ssum 
deallocate(a) 
call cpu_time(ts2) 
print *,'the time taken is ',ts2-ts1 

end program 

Ausgang ist

final sum 1.63840000204800000399876515667619840E+0036 
the time taken is 48.6228256 

C++ Code kompiliert und mit g++ -o bb1 code10.cpp

#include <iostream> 
#include <time.h> 
using namespace std; 

main() 
{ 
    long int n,i; 
    long double ssum; 

    clock_t starttime = clock(); 
    n=1600000000; 
    double *a = new double[n]; 
    ssum=0; 

    for(i=0; i<n; i++) 
    { 
     a[i]=i+1; 
     ssum=ssum+a[i]*a[i]*a[i]; 
    } 

    cout << "final sum " << ssum << endl; 
    delete [ ]a; 
    cout << "the time taken is " 
     << (double)(clock() - starttime)/(double)CLOCKS_PER_SEC 
     << endl; 
} 

Ausgang

final sum 1.6384e+36 
the time taken is 12.0104 
+0

ein besonderer Grund ein Array erstellen zu speichern 'n -> n + 1 '? Ich mag mich irren, aber durchläuft FORTRAN nicht alle Variablen, um zu finden, was Sie wollen? Das heißt, es würde durch 1,6 Milliarden Variablen iterieren, bevor Sie das gefunden haben, was Sie wollen? –

+0

das ist, weil in fortran Array Indizierung mit 1 beginnt, so ist es 1,2,3 .. aber in C++ Array-Indizierung beginnt mit 0, so ist es 0,1,2,3 – Guddu

+3

Es gibt keinen Punkt zu vergleichen Leistung ohne Einschalten Optimierung (zB 'g ++ -O2 ...'). –

Antwort

6

Ich bin kein Fortran-Experte, aber es scheint, dass

real (kind=16) :: ssum 

deklariert eine quadruple precision (16 Byte) Gleitkommazahl, die wahrscheinlich in Software auf Ihrer Hardware emuliert wird. Ihr C++ Code verwendet eine long double, die einer erweiterten Genauigkeit (10 Byte) Fließkommazahl entspricht, die von Ihrer Hardware ausgeführt werden kann (und viel schneller ist). Bitte beachten Sie, dass long double auf allen Plattformen keine 10-Byte-Gleitkommazahl ist, sondern auf einigen Plattformen beispielsweise double. Ich denke, das gilt für Windows und MSVC. Um eine erweiterte Präzision Gleitkommazahl in Fortran, Verwendung:

real (kind=10) :: ssum 
+0

aber 'sizeof (SSUM)' in meinem C++ Code Rückkehr annehmen kann '16' nicht' 10'. Also ist es immer noch 10-Byte-Genauigkeit und nur 16 Bytes im Speicher? – Guddu

+0

@Guddu: Ausführen von 'gcc -dM -E -

+0

Danke, Wiki-Seite auf 'long double' war auch hilfreich, es war mein Missverständnis, dass' long double' doppelt so genau ist wie 'double' – Guddu