2014-07-25 7 views
7

Nach this Artikel/Video:Doppel-Compilation von C-Code verringern Ausführungszeiten

GCC erkennt mehrere Architektur-abhängige Optimierungen für die Geschwindigkeit von C ausführbaren Dateien zu erhöhen. Eine ausführbare Datei durch GCC ein zweites Mal zu übergeben kann oft eine dramatische Verbesserung Verbesserung bieten.

Wenn Sie das Video auf dem Link angeschaut haben, können Sie sehen, dass diese Methode die Geschwindigkeit einer ausführbaren Datei verdoppelt. Ich bin mir nicht sicher, ob das allgemein ist.

Meine Frage ist: Warum passiert das?

Bonus: Was passiert, wenn wir ein kompiliertes Programm genau kompilieren?

+13

Das musste ein Scherz sein. Sehen Sie, wie der Code ein 'sleep (10)' enthält? Das ist ein Systemaufruf, bei dem der Prozess für zehn Sekunden inaktiviert wird. Warum sollte "Double Compiling" den Schlaf halbieren? Beachten Sie, dass das Poster die Dateien nach dem Ausführen des ersten Programms nicht auflistet. –

+0

@JoachimPileborg deshalb frage ich hier lol :) das ist das erste Mal, dass ich so etwas sehe –

+3

Die zehn Sekunden, die das erste Programm läuft, ist reichlich Zeit, die Quelle zu bearbeiten und umbenennen zu 'kompiliert' in einem Terminal nicht aufgezeichnet. Beachten Sie, dass Dateinamenerweiterungen (wie '.c') in POSIX-Systemen (wie Linux) optional sind. :) –

Antwort

46

Dies ist ein Scherz.

Weder gcc noch irgendein anderer Compiler kann Objektcode lesen, "kompilieren" und Objektcode erzeugen, der schneller ist.

Die nächste Sache ist Feedback gerichtete Zusammenstellung, wo Sie zunächst ein Programm mit Instrumentierung zusammenstellen (zB gcc --fprofile-generate), führen Sie das Programm, eine Datendatei über den Lauf (zB foo.gcda) zu erzeugen, und dann das Programm kompiliert wieder die Verwendung von gleicher Quellcode und die Datendatei als Eingabe für den Compiler (zB gcc --fprofile-use). Dies kann zu ziemlich bescheidenen Beschleunigungen führen, typischerweise zwischen 5% und 10% nach meiner Erfahrung.

Angenommen, Sie haben eine lange Kette von 50 if … else if Konstrukten (die nicht als switch umstrukturiert werden kann). Dies geschieht beispielsweise häufig in Monte-Carlo-Simulationen. Wenn Sie ein einigermaßen erfahrener Programmierer sind, werden Sie diese wahrscheinlich so bestellen, dass der Zweig, der am häufigsten verwendet wird, zuerst angezeigt wird. Die Idee ist, dass Sie zur Laufzeit keine Zeit verschwenden, wenn Sie 30 weniger wahrscheinliche Verzweigungen betrachten, bevor Sie die wahrscheinlichsten betrachten. Darüber hinaus werden Sie versuchen, diese Verzweigungen am wahrscheinlichsten zu sortieren, so dass im Durchschnitt die geringste Anzahl von Verzweigungstests ausgeführt wird, bevor die richtige gefunden wird. Beachten Sie, dass der Compiler keine Grundlage für die Bestellung dieser Verzweigungen hat, da die Information, dass eine wahrscheinlicher ist als eine andere, nicht im Quellcode enthalten ist. Das Beste, was getan werden kann, ist die Ausgabe der Verzweigungen in Quellreihenfolge.

Bei der klassischen feedbackgesteuerten Kompilierung erstellen Sie zuerst eine instrumentierte Version der ausführbaren Datei, die (wenn Sie sie ausführen) aufzeichnet, wie oft jede Verzweigung in eine Datendatei aufgenommen wird (oder nicht). Beim zweiten Kompilieren hat der Compiler empirische Daten von Laufzeit (die es normalerweise nicht hat), die verwendet werden können, um Tests neu anzuordnen und Verzweigungshinweise einzufügen, die den Code schneller ausführen ... zumindest mit ähnlichen Arbeitsauslastungen profiliertes Testprogramm.

Ich bin mir sicher, dass moderne feedbackgesteuerte Kompilation wesentlich anspruchsvoller ist, aber das ist die allgemeine Idee.

+4

Denken Sie daran, dass "Feedback-gerichtete Kompilierung" im Wesentlichen das ist, was ein Java "Just In Time Compiler" tut. –

+0

Nicht die gleiche Sache, aber [ein verwandtes Konzept wird hier nett illustriert] (http://stackoverflow.com/a/11227902/20670). –

Verwandte Themen