Clang lld-link führt keine LTO/Inlining durch

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Krishty
Establishment
Beiträge: 8229
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Clang lld-link führt keine LTO/Inlining durch

Beitrag von Krishty »

Windows. Clang 9.0.0 kompiliert mein Programm, linkt es, optimiert … und das Ergebnis ist eine einzige Katastrophe – von der Leistung her weit hinter Visual C++.

Ursache scheint zu sein, dass der Linker während der Link Time Optimization kein Inlining von nicht-inline-Funktionen durchführt. Beispielsweise habe ich in endian.cpp ein Dutzend Funktionen littleEndian(), die nichts anderes tun, als ihren Parameter direkt wieder zurückzugeben – weil sie pure Abstraktionshelfer sind. Visual C++ optimiert diese Aufrufe komplett weg. Clang nicht:

  mov eax, ecx
  call littleEndian

littleEndian(x):
  push rax
  mov dword ptr [rsp+4],ecx
  mov eax,dword ptr [rsp+4]
  pop rcx
  ret


What the fuck! Das sieht wie Debug-Code aus!

Die naheliegende Frage ist natürlich: Wie kompiliere ich?

Die C++-Quellen kompiliere ich mit

  clang++ -c -std=c++2a -fno-ms-compatibility -fno-ms-extensions -Wall -Wextra -Wpedantic -Wno-#pragma-messages -fno-exceptions -finline-functions -finline-hint-functions -MT -Os -flto -fmerge-all-constants -fvisibility=hidden -ffunction-sections -fdata-sections -gfull -gcodeview "foo.cpp" -o "foo.o"

Dann linke ich sie mit

  lld-link /debug /pdb:"foo.pdb" /subsystem:WINDOWS /out:"foo.exe" "foo.o" /opt:REF /opt:ICF

Ich beobachte folgendes:
  • Ersetze ich -Os durch -O0, wird der Code rapide größer. Durch -O2 oder -O3 ändert sich fast nix. Optimierung scheint also stattzufinden.
     
  • Ich setze extra -fvisibility=hidden damit Clang nicht mit irgendwelchem Linux-Shared-Object-Verhalten anfängt und nicht-statische, nicht-inline Funktionen nur noch durch explizite Aufrufe ansteuert. Das Flag ändert aber nichts am Kompilat.
     
  • Es gibt keine klare Dokumentation, wie LTO aktiviert wird.
    https://lld.llvm.org/ hat geschrieben:Link-time optimization (LTO) is supported by default. Essentially, all you have to do to do LTO is to pass the -flto option to clang. Then clang creates object files not in the native object file format but in LLVM bitcode format. LLD reads bitcode object files, compiles them using LLVM and emit an output file. Because in this way LLD can see the entire program, it can do the whole program optimization.
    Entferne ich den -flto-Schalter, wird das Kompilat eklatant größer, trotz -O2 oder -Os. Es scheint also durchaus globale Optimierung stattzufinden.
Was läuft schief?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8229
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Clang lld-link führt keine LTO/Inlining durch

Beitrag von Krishty »

Die LLVM-Webseite bietet für LLVM 9.0.1 keinen Windoze-Download an. Wenn man sich den Quelltext anschaut, existiert durchaus ein Link, ist aber auskommentiert. Ohne Erklärung.

Ich habe das mal heruntergeladen und installiert; keine Änderung.

Der Link führt ins github-Repo, und dort findet man dann auch viel frischere Binaries – etwa den 10.0.0 rc3.

Der bringt volle C++’20-Unterstützung und ist etwas strikter mit static bzw. inline auf constexpr auf namespace-Level, also musste ich ein Bisschen was anpassen.

clang++ beschwert sich auch, dass -MT und -Os nicht mehr unterstützt werden(?!?). Also habe ich die entfernt.

Das Ergebnis ist jedoch – zumindest an den Stellen, die ich verglichen habe – gleich.

Ich habe eben sichergestellt, dass Clang auch tatsächlich Bitcode-Dateien ausspuckt, denn das setzt LTO voraus. Die Dateien beginnen alle mit den Bytes BC.

Irgendwas mache ich total falsch. Nun schaue ich erstmal, wo die Optimierungsoptionen hingewandert sind.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Clang lld-link führt keine LTO/Inlining durch

Beitrag von Schrompf »

Ich bin überhaupt damit gescheitert, ein hinreichend komplexes Projekt mit -flto zu kompilieren. Du bist bereits deutlich weiter gekommen als ich. Sorry, kann Dir da nicht helfen. Außer vielleicht Dir ein wenig Zeitverschwendung zu ersparen: deren User-MailingList bounced bei dem Versuch, sich dafür zu registrieren. Verdammte Profis.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8229
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Clang lld-link führt keine LTO/Inlining durch

Beitrag von Krishty »

Schrompf hat geschrieben: 14.03.2020, 21:14Außer vielleicht Dir ein wenig Zeitverschwendung zu ersparen: deren User-MailingList bounced bei dem Versuch, sich dafür zu registrieren. Verdammte Profis.
Jetzt wo du es sagst: Da wollte ich mich vor zehn Jahren oder so mal registrieren, und da war die Registrierung überhaupt nicht möglich (Spam oder so).

Als jemand, der es in den letzten 15 Jahren nicht geschafft hat, mal substantiell was an ZFX zu verbessern, stimme ich dir zu: Verdammte Profis.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8229
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Clang lld-link führt keine LTO/Inlining durch

Beitrag von Krishty »

Irgendwas hat sich geändert – und das, obwohl meine Befehle exakt die selben sind wie zuvor. WTF.

Ich hatte ein wenig mit /opt:lldlto=3 und /opt:lldltojobs=8 experimentiert.

Nun wird definitiv geinlined und über Funktionsgrenzen optimiert. Ich habe aber dennoch viele Dutzend Funktionen mit nur einem oder zwei Befehlen Länge, und das Gesamtkompilat ist rund 70 % länger als Visual C++’. Alles fishy.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten