9 Stimmen

Was sind die wichtigsten Design-Entscheidungen, um einen extrem schnellen Compiler zu entwickeln?

Ich möchte wissen, wie man einen Compiler entwickelt, der sehr, sehr schnell kompiliert.

Zunächst möchte ich einige offensichtliche Missverständnisse in Bezug auf meine Frage ausräumen:

  1. Ich bin no Es geht um die Geschwindigkeit des vom Compiler erzeugten Codes. Es gibt bereits viele verfügbare Ressourcen, um zu lernen, wie man generierten Code optimiert. Was ich nicht finde, sind Informationen darüber, wie man die Compiler schnell.

  2. Ich bin auch nicht an einer Diskussion darüber interessiert, warum C++-Compiler generell langsamer sind als Java-Compiler (zum Beispiel). Ich bin daran interessiert, welche Techniken eingesetzt werden können, um den Compiler für eine bestimmte Sprache zu beschleunigen.

  3. Ich möchte auch nichts über verteilte Kompilierungssysteme wie Microsofts Incredibuild oder Unix' distcc hören. Diese Systeme geben Ihnen keine schneller Compilern, sie geben Ihnen nur mehr Kompilatoren. Das ist sicherlich nützlich, aber das ist nicht die Frage, die ich stelle. Ich möchte wissen, wie man einen schnellen Compiler für eine einzelne CPU entwickelt.

  4. Auch ccache ist nicht die Antwort, nach der ich suche. Das ist ein System, mit dem man die Verwendung des Compilers vermeiden kann, aber es macht den Compiler nicht schneller. Auch das ist nützlich, aber das ist nicht die Frage, die ich stelle.

Ich hoffe, meine Frage ist jetzt klar und deutlich. Aber vielleicht wird sie durch ein wenig Geschichte noch klarer.

C-Compiler waren früher sehr langsam. Dann, 1986, stellte THINK Technologies Lightspeed C für Macintosh vor, und es kompilierte Programme fast sofort. Lightspeed C war also viel schneller als alle anderen C-Compiler, dass es kaum einen Vergleich gab. (Vielleicht war Lightspeed C nicht der erste der neuen Generation von blitzschnellen Compilern, aber nach meiner Erfahrung war es der erste. Turbo Pascal kam schon früher [1983] auf den Markt, aber ich hatte keine Erfahrung damit, so dass ich nicht weiß, wie er in Bezug auf die Geschwindigkeit im Vergleich abschneidet).

Seitdem gibt es viele schnelle Compiler. Es scheint, dass es in den 1980er Jahren eine Art Quantensprung in der Compilertechnologie gab, und dass ist das, was ich zu verstehen versuche. Was war der Durchbruch?

Die Antwort ist vielleicht so einfach: Bei IDEs wie Lightspeed und Turbo hat der integrierte Editor den Quellcode bereits im RAM. Wenn der Compiler mit diesen Daten arbeitet, entfällt die Festplatten-E/A, die der langsamste Teil jedes Compilers ist. Das ist wahrscheinlich ein sehr wichtiger Beitrag zur Geschwindigkeitsverbesserung, wenn die Größe des Quellcodes im Verhältnis zur Speichergröße klein ist. (Damals waren die RAM-Größen viel kleiner, aber das galt auch für die typischen Programmgrößen.)

War es das? Oder gab es noch andere wichtige Innovationen? Und hat sich die Geschwindigkeit der Compiler seither wesentlich verbessert?

0voto

supercat Punkte 72939

Ich denke, eine der großen Veränderungen in Turbo Pascal war, dass bei vielen früheren Compilern/Assemblern/Linkern sowohl der Quellcode als auch der Objektcode auf der Festplatte lagen, ebenso wie Teile des Compilers/Assemblers/Linkers. Der Versuch, mehrere Dateien gleichzeitig auf einem einzigen Laufwerk zu lesen und zu schreiben, war oft mehr als doppelt so langsam wie das Lesen oder Schreiben einer einzigen Datei. Bei Turbo Pascal befand sich das gesamte Entwicklungssystem im RAM, und in vielen Fällen auch der Quell- oder Objektcode im RAM.

Gegen Ende der Lebensdauer des Commodore 64 gab es einen Assembler namens Fast Assembler, der den Basisinterpreter um Assembler-Opcodes und ein paar neue Direktiven erweiterte. Die ORG-Direktive setzte eine Zielcodestelle und ein "pass"-Flag. Wenn das "pass"-Flag nicht gesetzt war, würde jeder Opcode die Zielcodestelle um die Befehlsgröße erhöhen, aber keinen Code erzeugen und sich nicht über Verzweigungen außerhalb des Bereichs beschweren. Wenn das Pass-Flag gesetzt war, wurde Code erzeugt. Um ein Programm zu assemblieren, umgab man es mit einer for/next-Schleife, die dreimal durchlaufen wurde, wobei das "pass"-Flag beim letzten Mal gesetzt wurde. Da alles im Arbeitsspeicher gehalten wurde, war der Editier-Assemble-Test-Zyklus im Vergleich zu früheren Assemblern enorm schnell.

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