Ein einfacher Testfall zwischen clang ++ / g ++ / gfortran

8

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:

%Vor%

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:

  1. Warum wird g ++ generierter Code langsamer als gfortran? Da sie aus derselben Compiler-Familie stammen, bedeutet das, dass (dieser) Fortran-Code einfach in einen schnelleren Code übersetzt werden kann? Ist das bei Fortran vs C ++ generell der Fall?
  2. Warum macht 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

    
GradGuy 19.05.2013, 21:18
quelle

2 Antworten

1

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.

    
varepsilon 22.05.2013 08:15
quelle
1

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 ):

%Vor%

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.

    
steabert 22.05.2013 13:15
quelle

Tags und Links