Wie kann ich mein sehr großes Programm zum Verknüpfen bringen?

8

Unser nächstes Produkt ist zu groß geworden, um es auf einem Computer mit 32-Bit-Windows zu verlinken. Die Summe aller lib-Dateien überschreitet 2 GB und kann nur auf einer 64-Bit-Windows-Maschine verknüpft werden. Schließlich werden wir diese Grenze überschreiten, da unsere Software eher wächst als kontrahiert und wir einen 32-Bit-Linker (MS Visual Studio 2005) verwenden: Wir erwarten, dass Probleme auftreten, wenn unsere Lib-Größe insgesamt 3 GB überschreitet.

Wie kann ich die Größe der LIB-Dateien oder der OBJ-Dateien reduzieren, ohne den Code zu trimmen? Zum Beispiel verwenden wir viele Vorlagen: Gibt es eine Möglichkeit, ihren Fußabdruck zu reduzieren? Gibt es eine Möglichkeit, herauszufinden, was den Bloat dazu bringt, die .lib / .obj-Dateien zu untersuchen? Kann dies automatisiert werden und nicht mit dem Auge kontrolliert werden? 2.5Gb ist eine Menge zu durchschauender Text und vergleichen.

Externe Einschränkungen verhindern, dass wir etwas anderes als eine einzelne .exe-Datei versenden können, daher ist keine DLL-Lösung verfügbar.

    
hatcat 22.07.2010, 10:31
quelle

9 Antworten

3

Probieren Sie das Symbol Sortierung Programm aus, um Ihnen zu zeigen, wo die wichtigsten Bits von bloat in Ihrem Code sind. Wenn Sie sich nur die Größe der RAW-OBJ-Dateien ansehen, erhalten Sie eine vernünftige Vorstellung davon, wo Sie das Ziel angeben sollen.

    
the_mandrill 22.07.2010, 15:03
quelle
5

Ich hatte einmal an einem Projekt mit mehreren MLoC gearbeitet. Während unsere immer noch auf einer 32-Bit-Maschine verlinken würden, waren die Verbindungszeiten dort abgründig und wurden zu einem großen Problem, da Entwickler pro Arbeitstag nur ein Dutzend Bearbeitungs-Kompilier-Testzyklen hatten. (Die Kompilierungszeiten wurden durch verteilte Kompilierung ziemlich gut verarbeitet.)

Wir sind zu dynamischer Verknüpfung übergegangen. Das erhöhte die Startzeit, aber dies konnte durch das verzögerte Laden von DLLs gemanagt werden.

    
sbi 22.07.2010 10:44
quelle
5

Stellen Sie zuerst sicher, dass Sie mit der Option 'Für Größe optimieren' kompilieren. Wenn Sie das tun, würde ich nicht erwarten, dass zumindest ein Beitrag zur Code-Größe beiträgt. Der Compiler stellt einen Kompromiss für jeden Inlinenkandidaten her, der angibt, um wie viel (wenn überhaupt) die Codegröße erhöht wird, im Vergleich zu dem Leistungsschub, den es geben würde. Und wenn Sie die Größe optimieren, riskiert der Compiler nicht, dass der Code viel aufgebläht wird. (Beachten Sie, dass das Einfügen sehr kleiner Funktionen die Codegröße verringern kann)

Zweitens, haben Sie unity-Builds in Erwägung gezogen ? Das würde den Linker vollständig eliminieren, und mit nur einer Übersetzungseinheit würde es viel weniger Doppelarbeit und hoffentlich weniger Speicherbedarf geben.

Schließlich weiß ich, dass Visual Studio (oder möglicherweise das Windows SDK) einen 64-Bit-Compiler hat (das heißt, ein Compiler, der selbst eine 64-Bit-Anwendung ist, nicht nur ein Compiler, der 64-Bit-Code erzeugt). Überlegen Sie, das zu verwenden (Ich weiß nicht, ob es auch einen 64-Bit-Linker gibt)

Ich weiß nicht, dass der Linker mit dem gesetzten LARGEADDRESSAWARE-Flag erstellt wird. Wenn dies der Fall ist, kann der Prozess auf einem 64-Bit-Rechner statt der normalerweise 2 GB vollen 4 GB Speicher verbrauchen. (Bei Bedarf können Sie das Flag selbst hinzufügen, indem Sie den PE-Header ändern)

Vielleicht könnte auch die Begrenzung der Verknüpfung verschiedener Symbole helfen. Wenn Sie wissen, dass ein Symbol außerhalb der aktuellen Übersetzungseinheit nicht benötigt wird, fügen Sie es in einen anonymen Namespace ein. Das könnte dem Compiler ermöglichen, unbenutzte Symbole zu reduzieren, bevor er alles an den Linker weitergibt.

    
jalf 22.07.2010 12:33
quelle
2

OMFG !!!!! Das ist huuuuuge!

Abgesehen von der Tatsache, dass es zu groß ist, um vernünftig zu sein ... können Sie nicht dynamisches Linking verwenden, um das Chaos in der Kompilierzeit zu vermeiden und nur in Runtime zu verknüpfen, was notwendig ist (ich meine, Dlls werden gefragt) ?

    
helios 22.07.2010 10:35
quelle
2

Muss es eine große App sein?

Eine Option besteht darin, verschiedene Module in DLLs aufzuteilen und sie bei Bedarf zu laden / zu entladen.

Alternativ können Sie möglicherweise in mehrere Apps aufteilen und Daten mithilfe von zugeordnetem Speicher teilen, ein DBMS oder sogar einfache Datendateien pipettieren.

    
Michael J 22.07.2010 13:00
quelle
2

Finden Sie zuerst heraus, wie Sie die Größe, die von verschiedenen Funktionen verwendet wird, messen . Versuchen Sie nicht, die Verwendung der Vorlage oder andere Dinge zu ersetzen, weil Sie vermuten, dass dies einen wesentlichen Unterschied macht.

Ausführen

%Vor%

um herauszufinden, welche Abschnitte in Ihrer Binärdatei die enorme Größe verursachen. Haben Sie einen riesigen Debug Directory-Bereich? Streifen Symbole dann. Ist die Importadressentabelle groß? Überprüfen Sie die Tabelle und suchen Sie nach Symbolen, die Sie nicht benötigen (ein Problem mit Vorlagen besteht darin, dass Symbole von Vorlageninstanziierungen dazu neigen, sehr sehr groß zu sein). Eine ähnliche Analyse kann für das Ausnahmeverzeichnis, das COM-Deskriptorverzeichnis usw. durchgeführt werden.

    
Frerich Raabe 22.07.2010 14:49
quelle
0

Ich glaube nicht, dass es ein einzelnes Tool gibt, das Ihnen Statistiken geben kann, die Sie brauchen / brauchen. Die Verwendung von .map-Dateien oder des Dienstprogramms " dumpbin " mit dem Parameter " /SYMBOLS " sowie einige Nachbearbeitungen des erstellten Protokolls können Ihnen dabei helfen, das gewünschte Ergebnis zu erzielen.

Wenn die Statistik Ihren Verdacht auf das Aufblähen der Vorlage oder sogar ohne die Bestätigung bestätigt, kann es eine gute Idee sein, mehrere Dinge mit der Quelle zu tun:

  1. Versuchen Sie, explizite Instanziierungen zu verwenden und Vorlagendefinitionen in CPP-Dateien zu verschieben. Dies funktioniert natürlich nur, wenn Sie eine begrenzte und bekannte Menge von Typen / Werten haben, die Sie als Argumente für die Vorlagen verwenden.
  2. Fügen Sie weitere Abstraktion und / oder Indirektion hinzu. Faktorcode, der nicht von Ihren Vorlagenparametern in seine eigenen Basisklassen oder freien Funktionen abhängt. Wenn Sie über mehrere Schablonetypparameter verfügen, überprüfen Sie, ob Sie die einzelne Klassenvorlage nicht in mehrere Basisklassen aufteilen können, ohne die Vorlagenparameter zu überlappen. (Siehe Ссылка .)
  3. Versuchen Sie, das Pimpl-Idiom zu verwenden; Vermeiden Sie die Instanziierung von Vorlagen in Kopfzeilen, wenn möglich, instanziieren Sie sie nur in .cpp-Dateien.
  4. Vorlagen sind nett, aber manchmal funktionieren auch normale Klassen; z.B. Vermeiden Sie die Übergabe von Integer-Konstanten als Nicht-Typ-Template-Parameter, wenn Sie sie als Parameter an ctor.
  5. übergeben können
wilx 22.07.2010 14:25
quelle
0

@hatcat und @jalf: Es gibt tatsächlich eine vollständige Reihe von 64-Bit-Tools . Beispielsweise können Sie eine Umgebungsvariable festlegen:

%Vor%

und führen Sie dann Visual Studio (von der Entwicklerkonsole) aus.

    
Pablo H 04.10.2017 20:36
quelle
-1

Ich bin sehr skeptisch, dass Ihr tatsächlicher Code 2 GB beträgt; Wahrscheinlich kompilieren Sie eine Menge Informationen. Ziehen Sie in Betracht, einige dieser Informationen in eine Ressourcendatei zu verschieben und sie als separaten Schritt in die ausführbare Datei einzubetten.

    
Brian 22.07.2010 14:54
quelle

Tags und Links