Ich bin über diese Frage auf scicomp gestolpert, was die Berechnung einer Summe beinhaltet. Dort sehen Sie ein c ++ und ein ähnliches Fortran Implementierung. Interessanterweise sah ich die Fortran-Version um 32% schneller.
Ich dachte, ich war mir über ihr Ergebnis nicht sicher und versuchte, die Situation zu regenerieren. Hier sind die (sehr leicht) verschiedenen Codes, die ich ausgeführt habe:
c ++
%Vor%fortran
%Vor% Ich kompiliere die obigen Codes mit gcc 4.6.3
und clang 3.0
auf einer Ubuntu 12.04 LTS
Maschine alle mit -O3
Flag. Hier sind meine Zeiten:
gfortran
%Vor%g ++
%Vor%kling
%Vor% Interessanterweise kann ich auch sehen, dass der Code fortran
schneller ist als der c++
und ungefähr gleich 32%, wenn gcc
verwendet wird. Mit clang
kann ich jedoch sehen, dass der Code c++
tatsächlich um etwa 19% schneller läuft. Hier sind meine Fragen:
clang
hier so gut? Gibt es ein Fortran-Frontend für den llvm-Compiler? Wenn ja, wird der von diesem erzeugte Code noch schneller sein? UPDATE:
Die Verwendung von -ffast-math -O3
options erzeugt folgende Ergebnisse:
gfortran
%Vor%g ++
%Vor%kling
%Vor% Npw g++
version läuft so schnell wie gfortran
und immer noch clang
ist schneller als beide. Das Hinzufügen von -fcx-fortran-rules
zu den obigen Optionen ändert die Ergebnisse nicht wesentlich
Ich glaube, Ihr Problem liegt im Ausgabeteil. Es ist bekannt, dass C ++ - Streams ( std::cout
) oft sehr ineffizient sind. Während verschiedene Compiler dies optimieren können, ist es immer eine gute Idee, kritische Leistungsteile mit C printf
-Funktion anstelle von std::cout
neu zu schreiben.
Die Zeitunterschiede beziehen sich auf die Zeit, die zum Ausführen von pow
benötigt wird, da der andere Code relativ einfach ist. Sie können dies durch Profilerstellung überprüfen. Die Frage ist dann, was der Compiler macht, um die Potenzfunktion zu berechnen?
Meine Zeitvorgaben: ~ 1.20 s für die Fortran-Version mit gfortran -O3
und 1.07 s für die C ++ - Version, die mit g++ -O3 -ffast-math
kompiliert wurde. Beachten Sie, dass -ffast-math
für gfortran
nicht relevant ist, da pow
von einer Bibliothek aufgerufen wird, aber für g++
einen großen Unterschied darstellt.
In meinem Fall wird für gfortran
die Funktion _gfortran_pow_c8_i4
aufgerufen ( Quellcode ). Ihre Implementierung ist der übliche Weg, um ganzzahlige Potenzen zu berechnen. Mit g++
auf der anderen Seite ist es eine Funktionsvorlage aus der Bibliothek libstdc ++, aber ich weiß nicht, wie das implementiert ist. Anscheinend ist es etwas besser geschrieben / optimierbar. Ich weiß nicht, in welchem Umfang die Funktion im Handumdrehen kompiliert wird, wenn man bedenkt, dass es sich um eine Vorlage handelt. Für was es wert ist, die Fortran-Version kompiliert mit ifort
und C ++ Version kompiliert mit icc
(mit -fast
Optimierung Flag) geben beide die gleichen Timings, also denke ich, dass diese die gleichen Bibliotheksfunktionen verwenden.
Wenn ich in Fortran nur eine Potenzfunktion mit komplexer Arithmetik schreibe (explizit Real- und Imaginärteile schreiben), ist es so schnell wie die mit g++
kompilierte C ++ Version (aber dann verlangsamt -ffast-math
es, also blieb ich stecken nur zu -O3
mit gfortran
):
Nach meiner Erfahrung ist die Verwendung expliziter Real- und Imaginärteile in Fortran-Implementierungen schneller, obwohl es natürlich sehr bequem ist, die komplexen Typen zu verwenden.
Schlussbemerkung: Obwohl es nur ein Beispiel ist, ist der Weg, die Power-Funktion bei jeder Iteration aufzurufen, extrem ineffizient. Stattdessen sollten Sie a
natürlich bei jeder Iteration einfach multiplizieren.