Clang vs GCC - was erzeugt bessere Binärdateien? [geschlossen]

238

Ich verwende derzeit GCC, habe aber kürzlich Clang entdeckt und denke über einen Wechsel nach. Es gibt jedoch einen entscheidenden Faktor - die Qualität (Geschwindigkeit, Speicherbedarf, Zuverlässigkeit) der von ihm erzeugten Binärdateien - wenn gcc -O3eine Binärdatei erzeugt werden kann, die 1% schneller läuft oder 1% weniger Speicher benötigt, ist dies ein Deal-Breaker.

Clang bietet bessere Kompilierungsgeschwindigkeiten und einen geringeren Speicherbedarf zur Kompilierungszeit als GCC, aber ich bin wirklich an Benchmarks / Vergleichen der resultierenden kompilierten Software interessiert - können Sie mich auf einige hinweisen oder Ihre Erfahrungen beschreiben?

SF.
quelle
5
Scheint immer noch eine wertvolle Frage und Antwort zu sein, und viele sind interessiert.
YasserAsmi
9
@YasserAsmi: Und die beiden Metriken - Speicherbedarf und Ausführungsgeschwindigkeit - sind alles andere als willkürlich oder unterliegen einer "Meinung". Aber es scheint, dass sich die Krankheit der Physik ausbreitet. SE breitet sich hier aus und die Leute begannen zu stimmen, um zu schließen, ohne auch hier Details zum Fragetext zu lesen.
SF.
12
Die Frage fragt nach Benchmarks und Vergleichen. Die Antwort gibt beides. Warum ist diese Meinung nicht ein sachlicher Vergleich?
oemb1905
2
Ich verstehe nicht, warum diese Frage geschlossen wurde. Unabhängig davon, ob es sich um eine Meinung oder eine Tatsache handelt, möchten wir die Antwort wissen. Wenn Sie sie als geschlossen markieren, wird sie negativ angezeigt, wo es keine geben sollte.
Timothy Makobu
2
@ TomZych: Wenn Sie diese Faktoren kennen möchten, stellen Sie verschiedene Fragen. Dieser ist sehr spezifisch und eindeutig - er fragt nach Ausführungsgeschwindigkeit und Speicherbedarf. Möglicherweise interessieren Sie sich für andere Faktoren, die gut für Sie sind. Dies bedeutet nicht, dass diese Frage ungültig ist, sondern nur nicht Ihren persönlichen Interessen entspricht. Es ist, als wären Sie ein Java-Programmierer und möchten jede C # -Frage schließen, weil sie nicht über Java spricht.
SF.

Antworten:

239

Hier sind einige aktuelle, wenn auch enge Ergebnisse von mir mit GCC 4.7.2 und Clang 3.2 für C ++.

UPDATE: GCC 4.8.1 v Clang 3.3 Vergleich unten angefügt.

UPDATE: GCC 4.8.2 v Clang 3.4 Vergleich ist dem beigefügt.

Ich verwalte ein OSS-Tool, das für Linux sowohl mit GCC als auch mit Clang und mit dem Microsoft-Compiler für Windows erstellt wurde. Das Tool coan ist ein Präprozessor und Analysator für C / C ++ - Quelldateien und Codelines für solche: seine Hauptprofile für das rechnerische Abstiegs-Parsing und die Dateiverwaltung. Der Entwicklungszweig (auf den sich diese Ergebnisse beziehen) umfasst derzeit etwa 11.000 LOC in etwa 90 Dateien. Es ist jetzt in C ++ codiert, das reich an Polymorphismus und Vorlagen ist und dennoch in vielen Patches durch seine nicht allzu ferne Vergangenheit in zusammengehacktem C verstrickt ist. Die Bewegungssemantik wird nicht ausdrücklich ausgenutzt. Es ist Single-Threaded. Ich habe keine ernsthaften Anstrengungen unternommen, um es zu optimieren, während die "Architektur" so weitgehend ToDo bleibt.

Ich habe Clang vor 3.2 nur als experimentellen Compiler eingesetzt, da seine C ++ 11-Standardunterstützung trotz seiner überlegenen Kompilierungsgeschwindigkeit und Diagnose der aktuellen GCC-Version in der von coan ausgeübten Hinsicht hinterherhinkt. Mit 3.2 wurde diese Lücke geschlossen.

Mein Linux-Testkabel für aktuelle Coan-Entwicklungsprozesse verarbeitet ungefähr 70.000 Quelldateien in einer Mischung aus Parser-Testfällen mit einer Datei, Stresstests, die Tausende von Dateien verbrauchen, und Szenariotests, die weniger als 1 KB Dateien verbrauchen. Das Harness meldet nicht nur die Testergebnisse, sondern sammelt auch die Gesamtzahl der verbrauchten Dateien und die in coan verbrauchte Laufzeit (es übergibt einfach jede coan-Befehlszeile an den Linux- timeBefehl und erfasst und addiert die gemeldeten Zahlen). Das Timing wird durch die Tatsache geschmeichelt, dass eine beliebige Anzahl von Tests, die 0 messbare Zeit benötigen, alle 0 ergeben, aber der Beitrag solcher Tests ist vernachlässigbar. Die Timing-Statistiken werden am Ende folgendermaßen angezeigt make check:

coan_test_timer: info: coan processed 70844 input_files.
coan_test_timer: info: run time in coan: 16.4 secs.
coan_test_timer: info: Average processing time per input file: 0.000231 secs.

Ich habe die Leistung des Testkabels zwischen GCC 4.7.2 und Clang 3.2 verglichen, wobei alle Dinge außer den Compilern gleich waren. Ab Clang 3.2 benötige ich keine Präprozessor-Differenzierung mehr zwischen Code-Traktaten, die GCC kompiliert, und Clang-Alternativen. Ich habe jeweils dieselbe C ++ - Bibliothek (GCC) erstellt und alle Vergleiche nacheinander in derselben Terminalsitzung ausgeführt.

Die Standardoptimierungsstufe für meinen Release-Build ist -O2. Ich habe auch Builds bei -O3 erfolgreich getestet. Ich habe jede Konfiguration dreimal hintereinander getestet und die drei Ergebnisse mit den folgenden Ergebnissen gemittelt. Die Zahl in einer Datenzelle ist die durchschnittliche Anzahl von Mikrosekunden, die von der ausführbaren Coan-Datei benötigt werden, um jede der ~ 70K-Eingabedateien zu verarbeiten (Lese-, Analyse- und Schreibausgabe und Diagnose).

          | -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.7.2 | 231 | 237 |0.97 |
----------|-----|-----|-----|
Clang-3.2 | 234 | 186 |1.25 |
----------|-----|-----|------
GCC/Clang |0.99 | 1.27|

Es ist sehr wahrscheinlich, dass eine bestimmte Anwendung Eigenschaften aufweist, die den Stärken oder Schwächen eines Compilers nicht gerecht werden. Rigoroses Benchmarking verwendet verschiedene Anwendungen. Vor diesem Hintergrund sind die bemerkenswerten Merkmale dieser Daten:

  1. -O3-Optimierung war für GCC geringfügig schädlich
  2. -O3-Optimierung war für Clang von großem Vorteil
  3. Bei der -O2-Optimierung war GCC nur um einen Whisker schneller als Clang
  4. Bei der -O3-Optimierung war Clang wesentlich schneller als GCC.

Ein weiterer interessanter Vergleich der beiden Compiler ergab sich zufällig kurz nach diesen Erkenntnissen. Coan verwendet großzügig intelligente Zeiger, und einer davon wird in der Dateiverwaltung stark ausgeübt. Dieser spezielle Smart-Pointer-Typ wurde in früheren Releases aus Gründen der Compiler-Differenzierung typisiert, um zu sein, std::unique_ptr<X>ob der konfigurierte Compiler eine ausreichend ausgereifte Unterstützung für seine Verwendung als solche hatte, und ansonsten eine std::shared_ptr<X>. Die Tendenz zu std::unique_ptrwar dumm, da diese Zeiger tatsächlich herum übertragen wurden, aber std::unique_ptrwie die passende Option zum Ersetzen std::auto_ptrzu einem Zeitpunkt aussahen, als die C ++ 11-Varianten für mich neu waren.

Während experimenteller Builds, um das anhaltende Bedürfnis von Clang 3.2 nach dieser und einer ähnlichen Differenzierung zu messen, habe ich versehentlich gebaut, std::shared_ptr<X>als ich beabsichtigt hatte zu bauen std::unique_ptr<X>, und war überrascht zu beobachten, dass die resultierende ausführbare Datei mit der Standard-O2-Optimierung die schnellste I war hatte gesehen, manchmal 184 ms zu erreichen. pro Eingabedatei. Bei dieser einen Änderung des Quellcodes waren dies die entsprechenden Ergebnisse.

          | -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.7.2 | 234 | 234 |1.00 |
----------|-----|-----|-----|
Clang-3.2 | 188 | 187 |1.00 |
----------|-----|-----|------
GCC/Clang |1.24 |1.25 |

Die wichtigsten Punkte hier sind:

  1. Keiner der Compiler profitiert jetzt überhaupt von der -O3-Optimierung.
  2. Clang schlägt GCC auf jeder Optimierungsebene genauso wichtig.
  3. Die Leistung von GCC wird durch die Änderung des Smart-Pointer-Typs nur geringfügig beeinflusst.
  4. Die -O2-Leistung von Clang wird maßgeblich durch die Änderung des Smart-Pointer-Typs beeinflusst.

Vor und nach der Änderung des Smart-Pointer-Typs kann Clang bei -O3-Optimierung eine wesentlich schnellere ausführbare Coan-Datei erstellen und bei -O2 und -O3 eine ebenso schnellere ausführbare Datei erstellen, wenn dieser Zeigertyp der beste ist - std::shared_ptr<X>- für die Arbeit.

Eine offensichtliche Frage, die ich nicht kommentieren kann, ist, warum Clang in meiner Anwendung eine Beschleunigung von 25% -O2 finden sollte, wenn ein häufig verwendeter Smart-Pointer-Typ von eindeutig zu gemeinsam geändert wird, während GCC gleichgültig ist zur gleichen Änderung. Ich weiß auch nicht, ob ich die Entdeckung, dass Clangs -O2-Optimierung eine so große Sensibilität für die Weisheit meiner Smart-Pointer-Entscheidungen birgt, bejubeln oder aushöhlen sollte.

UPDATE: GCC 4.8.1 v clang 3.3

Die entsprechenden Ergebnisse sind jetzt:

          | -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.8.1 | 442 | 443 |1.00 |
----------|-----|-----|-----|
Clang-3.3 | 374 | 370 |1.01 |
----------|-----|-----|------
GCC/Clang |1.18 |1.20 |

Die Tatsache, dass alle vier ausführbaren Dateien jetzt eine viel längere durchschnittliche Zeit als zuvor benötigen, um eine Datei zu verarbeiten, spiegelt nicht die Leistung der neuesten Compiler wider. Dies liegt an der Tatsache, dass der spätere Entwicklungszweig der Testanwendung in der Zwischenzeit viel Analyse-Raffinesse angenommen hat und sich schnell bezahlt macht. Nur die Verhältnisse sind signifikant.

Die Punkte der Bemerkung sind jetzt nicht auffallend neu:

  • GCC ist der -O3-Optimierung gleichgültig
  • Clang profitiert nur sehr geringfügig von der -O3-Optimierung
  • Clang schlägt GCC auf jeder Optimierungsstufe um einen ähnlich wichtigen Vorsprung.

Vergleicht man diese Ergebnisse mit denen für GCC 4.7.2 und Clang 3.2, so fällt auf, dass GCC auf jeder Optimierungsstufe etwa ein Viertel des Clang-Vorsprungs zurückgefordert hat. Da die Testanwendung inzwischen stark entwickelt wurde, kann man dies nicht sicher auf einen Aufholprozess bei der Codegenerierung von GCC zurückführen. (Dieses Mal habe ich den Anwendungsschnappschuss notiert, aus dem die Timings abgerufen wurden, und kann ihn wieder verwenden.)

UPDATE: GCC 4.8.2 v clang 3.4

Ich habe das Update für GCC 4.8.1 v Clang 3.3 abgeschlossen und gesagt, dass ich mich für weitere Updates an dasselbe Coan-Snaphot halten würde. Aber ich habe mich stattdessen entschlossen, diesen Snapshot (Rev. 301) und den neuesten Entwicklungs-Snapshot zu testen, der die Testsuite (Rev. 619) besteht. Dies gibt den Ergebnissen ein wenig Länge, und ich hatte ein anderes Motiv:

In meinem ursprünglichen Beitrag wurde festgestellt, dass ich keine Anstrengungen unternommen hatte, um den Coan auf Geschwindigkeit zu optimieren. Dies war ab rev. 301. Nachdem ich jedoch den Zeitmessapparat in den Coan-Testgurt eingebaut hatte, starrten mich die Auswirkungen der letzten Änderungen auf die Leistung jedes Mal an, wenn ich die Testsuite durchführte. Ich sah, dass es oft überraschend groß war und dass der Trend stärker negativ war, als ich es von Funktionsgewinnen verdient hatte.

Durch rev. 308 Die durchschnittliche Verarbeitungszeit pro Eingabedatei in der Testsuite hatte sich seit der ersten Veröffentlichung hier mehr als verdoppelt. Zu diesem Zeitpunkt drehte ich meine 10-jährige Politik um, mich nicht um die Leistung zu kümmern. In der intensiven Flut von Revisionen war die Leistung von bis zu 619 immer eine Überlegung, und eine große Anzahl von ihnen ging lediglich dazu über, wichtige Lastträger auf grundlegend schnelleren Zeilen neu zu schreiben (allerdings ohne die Verwendung von nicht standardmäßigen Compilerfunktionen). Es wäre interessant zu sehen, wie jeder Compiler auf diese Kehrtwende reagiert.

Hier ist die jetzt bekannte Zeitmatrix für die letzten beiden Compiler-Builds von Rev. 301:

coan - rev.301 Ergebnisse

          | -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.8.2 | 428 | 428 |1.00 |
----------|-----|-----|-----|
Clang-3.4 | 390 | 365 |1.07 |
----------|-----|-----|------
GCC/Clang | 1.1 | 1.17|

Die Geschichte hier ist von GCC-4.8.1 und Clang-3.3 nur unwesentlich geändert. GCCs Auftritt ist eine Kleinigkeit besser. Clang's ist eine Kleinigkeit schlimmer. Lärm könnte das gut erklären. Clang hat immer noch einen Vorsprung -O2und -O3Margen, die in den meisten Anwendungen keine Rolle spielen würden, aber für einige von Bedeutung wären.

Und hier ist die Matrix für rev. 619.

coan - rev.619 Ergebnisse

          | -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.8.2 | 210 | 208 |1.01 |
----------|-----|-----|-----|
Clang-3.4 | 252 | 250 |1.01 |
----------|-----|-----|------
GCC/Clang |0.83 | 0.83|

Wenn man die Figuren 301 und 619 nebeneinander betrachtet, sprechen mehrere Punkte aus.

  • Ich wollte schnelleren Code schreiben, und beide Compiler bestätigen nachdrücklich meine Bemühungen. Aber:

  • GCC zahlt diese Bemühungen weitaus großzügiger zurück als Clang. Bei der -O2 Optimierung ist Clangs 619-Build 46% schneller als sein 301-Build: Bei -O3Clangs Verbesserung 31%. Gut, aber auf jeder Optimierungsstufe ist der 619-Build von GCC mehr als doppelt so schnell wie der 301.

  • GCC kehrt Clangs frühere Überlegenheit mehr als um. Und auf jeder Optimierungsstufe schlägt GCC Clang jetzt um 17%.

  • Clangs Fähigkeit im 301-Build, durch -O3Optimierung mehr Hebelkraft als GCC zu erzielen, ist im 619-Build nicht mehr vorhanden. Keiner der Compiler profitiert sinnvoll von -O3.

Ich war von dieser Umkehrung des Glücks ausreichend überrascht, dass ich vermutete, dass ich versehentlich einen trägen Build von Clang 3.4 selbst erstellt habe (da ich ihn aus dem Quellcode erstellt habe). Also habe ich den 619-Test mit Clang 3.3 meiner Distribution wiederholt. Die Ergebnisse waren praktisch die gleichen wie für 3.4.

Was die Reaktion auf die Kehrtwende betrifft: Bei den Zahlen hier hat Clang viel besser als GCC abgeschnitten, als ich ihm keine Hilfe gegeben habe. Als ich mich entschied zu helfen, hat GCC einen viel besseren Job gemacht als Clang.

Ich erhebe diese Beobachtung nicht zu einem Prinzip, aber ich nehme die Lektion: "Welcher Compiler erzeugt die besseren Binärdateien?" ist eine Frage, bei der es, selbst wenn Sie die Testsuite angeben, zu der die Antwort relativ sein soll, nicht eindeutig darum geht, nur die Binärdateien zeitlich zu steuern.

Ist Ihre bessere Binärdatei die schnellste Binärdatei oder diejenige, die billig gestalteten Code am besten kompensiert? Oder kompensieren Sie am besten teuer gestalteten Code, bei dem Wartbarkeit und Wiederverwendung Vorrang vor Geschwindigkeit haben? Dies hängt von der Art und dem relativen Gewicht Ihrer Motive für die Erstellung der Binärdatei sowie von den Einschränkungen ab, unter denen Sie dies tun.

Wenn Sie sich auf jeden Fall für das Erstellen der "besten" Binärdateien interessieren, sollten Sie immer wieder überprüfen, wie aufeinanderfolgende Iterationen von Compilern Ihre Vorstellung von "den besten" über aufeinanderfolgende Iterationen Ihres Codes hinweg liefern.

Mike Kinghan
quelle
9
Warum klirrt es schneller? Beispielsweise verwendete der Intel-Compiler Spezialitäten von Intel-Chips. Was nutzt Clang, um sich einen Vorteil zu verschaffen? Kann der Code so umgeschrieben werden, dass gcc die gleiche Leistung hat?
kirill_igum
27
@krill_igum GCC und clang sind verschiedene (enorm komplexe) Programme, die von verschiedenen Gruppen von Programmierern geschrieben wurden, um denselben Job zu erledigen: Quellcode in Objektcode übersetzen. Es ist fast unvermeidlich, dass einer von ihnen diese Aufgabe zu jedem Zeitpunkt messbar besser als der andere in einem ausgewählten Test erledigt. Es muss kein spezielles "Ding" geben, das der Gewinner "benutzt", um "einen Vorteil zu erzielen", und da beide Programme Open Source sind, haben sie keine Geheimnisse voreinander.
Mike Kinghan
3
Es ist möglich kcachegrind, die Funktionen zu bestimmen, bei denen sich die generierten ausführbaren Dateien in der Leistung unterscheiden.
4
-1: Dies ist eher ein Roman (oder Blog-Beitrag) als eine Antwort.
John Saunders
60
@ JohnSaunders: Was für eine Person eine detaillierte, ausführliche Antwort ist, für eine andere ist ein Roman, der ihrer Aufmerksamkeit nicht würdig ist. Sag mir, was diese beiden Menschen auszeichnet.
SF.
48

Phoronix hat einige Benchmarks durchgeführt , aber es handelt sich um eine Snapshot-Version von Clang / LLVM von vor einigen Monaten. Das Ergebnis war, dass die Dinge mehr oder weniger ein Schub waren; Weder GCC noch Clang sind in allen Fällen definitiv besser.

Da Sie den neuesten Clang verwenden würden, ist er möglicherweise etwas weniger relevant. Andererseits wird GCC 4.6 anscheinend einige wichtige Optimierungen für Core 2 und i7 haben.

Ich denke, Clangs schnellere Kompilierungsgeschwindigkeit wird für Originalentwickler besser sein, und wenn Sie den Code in die Welt hinausschieben, Linux-Distribution / BSD / etc. Endbenutzer verwenden GCC für die schnelleren Binärdateien.

Nietzche-jou
quelle
2
Gerade heute habe ich ein paar Benchmarks für die Clang-Kompilierungsgeschwindigkeit durchgeführt und es ist sehr enttäuschend für reines C. Das Kompilieren von 35 C-Dateien mit 270 KLOC-Clang war nur 25% schneller. Wenn ich sehe, wie schnell tinycc unter Linux ist, ist das ein schlechtes Ergebnis für einen neuen geschriebenen Compiler. Bei Verwendung der Optimierungen -O2 / -O3 wird es besser, aber da sie für die Release-Erstellung verwendet werden, spielt die Compilerleistung in diesen Fällen keine Rolle.
Lothar
7
@mcandre Vielleicht wurde Nietzche-jou mit Clang kompiliert, während Sie mit GCC kompiliert wurden.
Mateen Ulhaq
18

Die Tatsache, dass Clang Code schneller kompiliert, ist möglicherweise nicht so wichtig wie die Geschwindigkeit der resultierenden Binärdatei. Hier finden Sie jedoch eine Reihe von Benchmarks .

mcandre
quelle
12
Eigentlich schon. Während der Entwicklung sind die Kompilierungszeit (und der Ressourcenverbrauch aufgrund der Kompilierung) viel mehr ein Engpass als die binäre Leistung. Schließlich kompilieren wir zu diesem Zeitpunkt im Debug-Modus. Erst wenn die Phase zum Testen und Versenden gekommen ist, wechseln Sie in den Freigabemodus und versuchen, eine Binärdatei so schnell wie möglich zu erhalten.
Matthieu M.
3
@ Matthieu M: Ich schwöre, diese Antwort lautete "Mai ...", als würde er ein potenzielles Problem ansprechen. Ich denke, vielleicht war es erwähnenswert, weil es, wissen Sie, mit dem OP zu tun hatte.
JM Becker
Stimmen Sie zu, obwohl alle guten Punkte hier. Ich würde lieber ein 2. oder 3. RAID 0-Laufwerk, eine SSD oder mehr und schnelleres RAM einwerfen und die beste EXE-Leistung erzielen - vorausgesetzt, diese Maßnahme kann Sie zur Parität oder zum Schließen bringen. Manchmal ist es auch hilfreich, mit mehr als einem Compiler zu entwickeln. Es kann Sie auf nicht portierbare Funktionen aufmerksam machen UND Fehler abfangen, die ansonsten unentdeckt bleiben, oder zu Tagen verschwendeter Zeit führen, die versucht werden, Code zu debuggen, auf den ein besserer Compiler gewarnt hätte.
Ich habe heute versucht, einen von mir geschriebenen, leistungskritischen Ganzzahlcode zu vergleichen, und GCC lief viel schneller (22S clang-llvm 25S), wobei sowohl -O2 als auch -O3 verwendet wurden. Denken Sie daran, dass die Verwendung von Compiler-Schaltern (gcc oder clang) die meisten nicht standardmäßigen Funktionen und statischen Warnungen abdeckt. In Ihrem eigenen großen Projekt, in dem Sie den Code anderer Benutzer nicht stapelweise kompilieren, machen Sie in Ihrem Build-System etwas falsch, wenn die Kompilierungszeit die Verbindungszeit dominiert. Es gibt Tools wie ccache.samba.org , die helfen, wenn Sie häufig sauber machen. Ein weiteres Problem beim Wechseln von Compilern ist die ständige Investition in das Testen / Validieren, die weggeworfen wird.
Rob11311
code.google.com/p/distcc ist ein weiteres Projekt, das Massenkompilierungszeiten beschleunigen kann, wenn eine gesamte Bibliothek aufgrund von Änderungen der Datenstruktur oder zu Überprüfungs- / Validierungszwecken neu kompiliert werden muss
Rob11311
11

Es gibt insgesamt nur einen sehr geringen Unterschied zwischen GCC 4.8 und Clang 3.3 in Bezug auf die Geschwindigkeit der resultierenden Binärdatei. In den meisten Fällen funktioniert der von beiden Compilern generierte Code ähnlich. Keiner dieser beiden Compiler dominiert den anderen.

Benchmarks, die darauf hinweisen, dass zwischen GCC und Clang eine erhebliche Leistungslücke besteht, sind zufällig.

Die Programmleistung wird durch die Wahl des Compilers beeinflusst. Wenn ein Entwickler oder eine Gruppe von Entwicklern ausschließlich GCC verwendet, ist zu erwarten, dass das Programm mit GCC etwas schneller ausgeführt wird als mit clang und umgekehrt.

Aus Entwicklersicht besteht ein bemerkenswerter Unterschied zwischen GCC 4.8+ und Clang 3.3 darin, dass GCC über die -OgBefehlszeilenoption verfügt . Diese Option ermöglicht Optimierungen, die das Debuggen nicht beeinträchtigen, sodass beispielsweise immer genaue Stapelspuren abgerufen werden können. Das Fehlen dieser Option in clang macht es für einige Entwickler schwieriger, clang als optimierenden Compiler zu verwenden.


quelle
In letzter Zeit (3.3 und 4.8) sehe ich nicht einmal einen großen Unterschied zwischen der Kompilierungszeit. (in "meinen" Programmen mit Kompilierungszeiten zwischen 10 Sekunden und 30 Sekunden).
AlfC
9

Die einzige Möglichkeit, dies festzustellen, besteht darin, es zu versuchen. FWIW Ich habe einige wirklich gute Verbesserungen mit Apples LLVM gcc 4.2 im Vergleich zum regulären gcc 4.2 (für x86-64-Code mit ziemlich viel SSE) gesehen, aber YMMV für verschiedene Codebasen. Angenommen, Sie arbeiten mit x86 / x86-64 und kümmern sich wirklich um die letzten paar Prozent, dann sollten Sie auch Intels ICC ausprobieren, da dies häufig gcc schlagen kann - Sie können eine 30-Tage-Evaluierungslizenz von intel.com erhalten und versuche es.

Paul R.
quelle
8

Ein besonderer Unterschied, den ich bei gcc 5.2.1 und clang 3.6.2 festgestellt habe, ist, dass Sie eine kritische Schleife haben wie:

for (;;) {
    if (!visited) {
        ....
    }
    node++;
    if (!*node) break;
  }

Dann wird gcc beim Kompilieren mit -O3oder -O2die Schleife achtmal spekulativ abrollen. Clang wird es überhaupt nicht abrollen. Durch Versuch und Irrtum stellte ich fest, dass in meinem speziellen Fall mit meinen Programmdaten die richtige Menge an Abrollen fünf beträgt, also gcc overshot und clang undershot. Das Überschießen war jedoch nachteiliger für die Leistung, so dass gcc hier viel schlechter abschnitt.

Ich habe keine Ahnung, ob der Unterschied beim Abrollen ein allgemeiner Trend ist oder nur etwas, das für mein Szenario spezifisch war.

Vor einiger Zeit habe ich ein paar Garbage Collectors geschrieben , um mir mehr über die Leistungsoptimierung in C beizubringen. Zumal es bei der Speicherbereinigung hauptsächlich um das Verfolgen und Kopieren von Speicher durch Zeiger geht.

Die Ergebnisse sind (Zahlen in Sekunden):

+---------------------+-----+-----+
|Type                 |GCC  |Clang|
+---------------------+-----+-----+
|Copying GC           |22.46|22.55|
|Copying GC, optimized|22.01|20.22|
|Mark & Sweep         | 8.72| 8.38|
|Ref Counting/Cycles  |15.14|14.49|
|Ref Counting/Plain   | 9.94| 9.32|
+---------------------+-----+-----+

Dies ist alles reiner C-Code und ich erhebe keinen Anspruch auf die Leistung eines Compilers beim Kompilieren von C ++ - Code.

Unter Ubuntu 15.10, x86.64 und einem AMD Phenom (tm) II X6 1090T-Prozessor.

Björn Lindqvist
quelle
4

Grundsätzlich lautet die Antwort: Es kommt darauf an. Es gibt viele, viele Benchmarks, die sich auf verschiedene Arten von Anwendungen konzentrieren.

Mein Benchmark für meine App lautet: gcc> icc> clang.

Es gibt seltene E / A-Vorgänge, aber viele CPU-Float- und Datenstrukturoperationen.

Kompilierungsflags sind -Wall -g -DNDEBUG -O3.

https://github.com/zhangyafeikimi/ml-pack/blob/master/gbdt/profile/benchmark

Kimi
quelle