Wenn ich mich richtig an den Kurs meines Compilers erinnere, hat der typische Compiler die folgende vereinfachte Gliederung:
- Einen lexikalischen Analysator Scans (oder einige Anrufe Abtastfunktion auf) der Quellcode Zeichen- für -Zeichen -
- Die Zeichenfolge der eingegebenen Zeichen wird anhand des Lexemwörterbuchs auf Gültigkeit überprüft
- Wenn das Lexem gültig ist, wird es als das Token klassifiziert, dem es entspricht
- Der Parser überprüft die Syntax der Tokenkombination. Token für Token .
Ist es theoretisch machbar, den Quellcode in Viertel aufzuteilen (oder welchen Nenner auch immer) und den Scan- und Parsing-Prozess mit mehreren Threads auszuführen? Gibt es Compiler, die Multithreading verwenden?
multithreading
compiler
parsing
8 Protonen
quelle
quelle
Antworten:
Große Softwareprojekte bestehen in der Regel aus vielen Kompilierungseinheiten, die relativ unabhängig kompiliert werden können. Daher wird die Kompilierung häufig mit einer sehr groben Granularität parallelisiert, indem der Compiler mehrmals parallel aufgerufen wird. Dies geschieht auf der Ebene der Betriebssystemprozesse und wird vom Build-System und nicht vom eigentlichen Compiler koordiniert. Mir ist klar, dass Sie dies nicht gefragt haben, aber das kommt der Parallelisierung in den meisten Compilern am nächsten.
Warum das? Ein Großteil der Arbeit, die Compiler leisten, lässt sich nicht ohne weiteres parallelisieren:
Danach wird es etwas einfacher. Die Typprüfung und -optimierung sowie die Codegenerierung können im Prinzip bei der Funktionsgranularität parallelisiert werden. Ich weiß immer noch von wenigen Compilern, die dies tun, vielleicht, weil es ziemlich schwierig ist, eine so große Aufgabe gleichzeitig zu erledigen. Sie müssen auch berücksichtigen, dass die meisten großen Softwareprojekte so viele Kompilierungseinheiten enthalten, dass der Ansatz "Mehrere Compiler gleichzeitig ausführen" völlig ausreicht, um alle Kerne (und in einigen Fällen sogar eine gesamte Serverfarm) zu belegen. Bei umfangreichen Kompilierungsaufgaben kann die Datenträger-E / A ebenso ein Engpass sein wie die eigentliche Kompilierungsarbeit.
Trotzdem kenne ich einen Compiler, der die Arbeit der Codegenerierung und -optimierung parallelisiert. Der Rust-Compiler kann die Back-End-Arbeit (LLVM, die eigentlich Codeoptimierungen enthält, die traditionell als "Middle-End" gelten) auf mehrere Threads aufteilen. Dies wird als "Code-Gen-Einheiten" bezeichnet. Im Gegensatz zu den anderen oben diskutierten Parallelisierungsmöglichkeiten ist dies wirtschaftlich, weil:
quelle
Kompilierung ist ein "peinlich paralleles" Problem.
Niemand kümmert sich um die Zeit zum Kompilieren einer Datei. Die Leute kümmern sich um die Zeit des Kompilierens von 1000 Dateien. Bei 1000 Dateien kann jeder Prozessorkern problemlos eine Datei gleichzeitig kompilieren, sodass alle Kerne voll ausgelastet sind.
Tipp: "make" verwendet mehrere Kerne, wenn Sie die richtige Befehlszeilenoption angeben. Andernfalls wird eine Datei nach der anderen auf einem 16-Kern-System kompiliert. Das heißt, Sie können die Kompilierung 16-mal schneller machen, indem Sie Ihre Build-Optionen in einer Zeile ändern.
quelle