17 Stimmen

Wie finde ich heraus, warum g++ für eine bestimmte Datei sehr viel Zeit benötigt?

Ich baue eine Menge von automatisch generierten Code, einschließlich einer besonders großen Datei (~15K Zeilen), mit einem mingw32 Cross-Compiler auf Linux. Die meisten Dateien sind extrem schnell, aber diese eine große Datei nimmt eine unerwartet lange Zeit (~15 Minuten) zu kompilieren.

Ich habe versucht, verschiedene Optimierungsflags zu manipulieren, um zu sehen, ob sie irgendeine Wirkung haben, ohne Erfolg. Was ich wirklich brauche, ist eine Möglichkeit, herauszufinden, was g++ tut, das so lange dauert. Gibt es (relativ einfache) Möglichkeiten, g++ dazu zu bringen, eine Ausgabe über die verschiedenen Phasen der Kompilierung zu erzeugen, um mir dabei zu helfen, die Ursache des Problems einzugrenzen?

Leider bin ich nicht in der Lage, diesen Cross-Compiler neu zu erstellen, so dass es nicht möglich ist, dem Compiler Debugging-Informationen hinzuzufügen und ihn durchzugehen.

Was in der Datei enthalten ist:

  • ein Bündel von Includes
  • eine Reihe von String-Vergleichen
  • eine Reihe von Wenn-dann-Prüfungen und Konstruktoraufrufe

Die Datei ist eine Fabrik für die Erzeugung einer Vielzahl verschiedener spezifischer Unterklassen einer bestimmten übergeordneten Klasse. Die meisten der Includes sind jedoch nicht sonderlich ausgefallen.


Die Ergebnisse von -ftime-report, wie von Neil Butterworth vorgeschlagen, zeigen, dass die Phase "Lebensanalyse" 921 Sekunden dauert, was den größten Teil der 15 Minuten in Anspruch nimmt.

Es scheint, dass dies während der Datenflussanalyse geschieht. Die Datei selbst besteht aus einer Reihe von bedingten String-Vergleichen, bei denen ein Objekt nach dem als String angegebenen Klassennamen konstruiert wird.

Wir denken, dass die Änderung dieses Punktes in eine Abbildung von Namen auf Funktionszeiger die Dinge ein wenig verbessern könnte, also werden wir das versuchen.


Durch die Generierung einer Reihe von Fabrikfunktionen (pro Objekt) und die Erstellung einer Map vom String-Namen des Objekts zu einem Zeiger auf seine Fabrikfunktion konnte die Kompilierzeit von ursprünglich 15 Minuten auf etwa 25 Sekunden reduziert werden, was für jeden eine enorme Zeitersparnis bei der Erstellung von Builds bedeutet.

Nochmals vielen Dank an Neil Butterworth für den Hinweis auf -ftime-report.

27voto

Das wird nicht alle gewünschten Details liefern, aber versuchen Sie, mit dem -v (ausführlich) und -ftime-report Flaggen. Letzteres liefert eine Zusammenfassung dessen, was der Compiler gemacht hat.

4voto

Goz Punkte 59671

Wahrscheinlich enthält es TONNEN von Includes. Ich glaube, dass -MD alle Include-Dateien in einer gegebenen CPP-Datei auflistet (das beinhaltet Includes von Includes und so weiter).

2voto

Tristram Gräbener Punkte 9391

Was G++ im Allgemeinen verlangsamt, sind Vorlagen. Boost zum Beispiel liebt es, sie zu verwenden. Das bedeutet schönen Code, tolle Leistung, aber schlechte Kompiliergeschwindigkeit.

Andererseits scheinen 15 Minuten extrem lang zu sein. Nach kurzem Googeln scheint es ein häufiges Problem mit mingw zu sein

2voto

Josh Kelley Punkte 52169

Ich würde die #if 0 / #endif um große Teile der Quelldatei von der Kompilierung auszuschließen. Wiederholen Sie den Vorgang mit verschiedenen Codeblöcken, bis Sie herausgefunden haben, welcher Block bzw. welche Blöcke langsam sind. Für den Anfang können Sie feststellen, ob Ihr #include sind das Problem, indem man #if 0 / #endif um alles auszuschließen, außer dem #include 's.

1voto

Thomas Matthews Punkte 54757

Ein weiteres Verfahren, das Sie ausprobieren können, ist das Hinzufügen von "Fortschrittsmarkierungen". pragma s in Ihren Code einfügen, um den Teil des Codes abzufangen, der zu viel Zeit in Anspruch nimmt. Der Visual Studio-Compiler bietet #pragma message() obwohl es kein Standard-Pragma für diese Vorgehensweise gibt.

Setzen Sie eine Markierung am Anfang des Codes und eine Markierung am Ende des Codes. Die Endmarkierung könnte ein #error da Sie sich nicht um den Rest der Quelldatei kümmern. Verschieben Sie die Markierungen entsprechend, um den Abschnitt des Codes einzufangen, der am längsten dauert.

Nur so ein Gedanke...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X