it-swarm.dev

JIT-Compiler für C, C ++ und dergleichen

Gibt es einen Just-in-Time-Compiler für kompilierte Sprachen wie C und C++? (Die ersten Namen, die mir in den Sinn kommen, sind Clang und LLVM! Aber ich glaube nicht, dass sie dies derzeit unterstützen.)

Erläuterung:

Ich denke, die Software könnte von Feedback zur Laufzeitprofilerstellung und einer aggressiv optimierten Neukompilierung von Hotspots zur Laufzeit profitieren, selbst für auf Computer kompilierte Sprachen wie C und C++.

Die profilgesteuerte Optimierung erledigt einen ähnlichen Job, aber mit dem Unterschied wäre eine JIT in verschiedenen Umgebungen flexibler. In PGO führen Sie Ihre Binärdatei aus, bevor Sie sie freigeben. Nachdem Sie es veröffentlicht haben, werden keine zur Laufzeit gesammelten Umgebungs-/Eingabe-Feedbacks verwendet. Wenn also das Eingabemuster geändert wird, wird die Leistung beeinträchtigt. Aber JIT funktioniert auch unter diesen Bedingungen gut.

Ich denke jedoch, dass es umstritten ist, ob der Leistungsvorteil der JIT-Kompilierung den eigenen Overhead überwiegt.

33

[Eine ganz andere Antwort finden Sie im Bearbeitungsverlauf, die jetzt im Grunde veraltet ist.]

Ja, es gibt einige JIT-Compiler für C und/oder C++.

CLing (wie Sie vielleicht aus dem Spiel erraten) basiert auf Clang/LLVM. Es wirkt wie ein Dolmetscher. Das heißt, Sie geben ihm einen Quellcode, geben einen Befehl zum Ausführen und es wird ausgeführt. Der Schwerpunkt liegt hier in erster Linie auf Komfort und schnellem Kompilieren, nicht auf maximaler Optimierung. Obwohl dies technisch eine Antwort auf die Frage selbst ist, entspricht dies nicht wirklich der Absicht des OP.

Eine andere Möglichkeit ist NativeJIT . Das passt etwas anders zur Frage. Insbesondere akzeptiert es keinen C- oder C++ - Quellcode und kompiliert ihn und führt ihn aus. Es ist vielmehr ein kleiner Compiler, den Sie in Ihr C++ - Programm kompilieren können. Es akzeptiert einen Ausdruck, der im Grunde genommen als EDSL in Ihrem C++ - Programm ausgedrückt wird, und generiert daraus den tatsächlichen Maschinencode, den Sie dann ausführen können. Dies passt viel besser zu einem Framework, in dem Sie den größten Teil Ihres Programms mit einem normalen Compiler kompilieren können, aber einige Ausdrücke haben, die Sie erst zur Laufzeit kennen und die Sie mit etwas ausführen möchten, das sich der optimalen Ausführungsgeschwindigkeit nähert.

Was die offensichtliche Absicht der ursprünglichen Frage betrifft, denke ich, dass der grundlegende Punkt meiner ursprünglichen Antwort immer noch besteht: Während sich ein JIT-Compiler an solche Dinge wie Daten anpassen kann Das ist von einer Ausführung zur nächsten unterschiedlich oder variiert sogar dynamisch während einer einzelnen Ausführung. Die Realität ist, dass dies zumindest in der Regel relativ wenig Unterschied macht. In den meisten Fällen bedeutet das Ausführen eines Compilers zur Laufzeit, dass Sie auf einige Optimierungen verzichten müssen. Das Beste, auf das Sie normalerweise hoffen, ist, dass es nahezu so schnell ist, wie es ein herkömmlicher Compiler produzieren würde.

Obwohl es möglich ist, Situationen zu postulieren, in denen Informationen, die einem JIT-Compiler zur Verfügung stehen, es ihm ermöglichen könnten, wesentlich besseren Code als ein herkömmlicher Compiler zu generieren, geschieht dies in der Praxis scheinen ziemlich ungewöhnlich zu sein (und in den meisten Fällen, in denen ich das Geschehen überprüfen konnte, lag es wirklich an einem Problem im Quellcode, nicht am statischen Kompilierungsmodell).

33
Jerry Coffin

Ja, es gibt JIT-Compiler für C++. Aus reiner Leistungsperspektive denke ich, dass Profile Guided Optimization (PGO) immer noch überlegen ist.

Dies bedeutet jedoch nicht, dass die JIT-Kompilierung in der Praxis noch nicht verwendet wird. Beispiel: Apple verwendet LLVM als JIT für die OpenGL-Pipeline. In dieser Domäne verfügen Sie zur Laufzeit über erheblich mehr Informationen, mit denen viel toter Code entfernt werden kann.

Eine weitere interessante Anwendung von JIT ist Cling, ein interaktiver C++ - Interpreter, der auf LLVM und Clang basiert: https://root.cern.ch/cling

Hier ist eine Beispielsitzung:

[cling]$ #include <iostream>
[cling]$ std::cout << "Hallo, world!" << std::endl;
Hallo, world!
[cling]$ 3 + 5
(int const) 8
[cling]$ int x = 3; x++
(int) 3
(int const) 3
[cling]$ x
(int) 4

Es ist kein Spielzeugprojekt, aber es wird tatsächlich im CERN verwendet, um beispielsweise den Code für den Large Hadron Collider zu entwickeln.

11
Philipp Claßen

C++/CLI ist jitted. Zugegeben, C++/CLI ist nicht C++, aber es ist ziemlich nah. Das heißt, Microsofts JIT führt nicht die super cleveren/niedlichen Optimierungen auf der Basis von Laufzeitverhalten durch, nach denen Sie fragen, zumindest meines Wissens nicht. Das hilft also wirklich nicht.

http://nestedvm.ibex.org/ verwandelt MIPS in Java Bytecode, der dann gesendet wird. Das Problem bei diesem Ansatz aus Ihrer Frage ist, dass Sie wegwerfen Viele nützliche Informationen, wenn sie bei der JIT ankommen.

7
Logan Capaldo

Erstens gehe ich davon aus, dass Sie eher einen Tracing-Jit als einen Methoden-Jit möchten.

Der beste Ansatz wäre, den Code in llvm IR zu kompilieren und dann den Ablaufverfolgungscode hinzuzufügen, bevor eine native ausführbare Datei erstellt wird. Sobald ein Codeblock ausreichend gut verwendet wird und genügend Informationen über die Werte (nicht die Typen wie in dynamischen Sprachen) von Variablen gesammelt wurden, kann der Code (aus dem IR) mit Wachen neu kompiliert werden auf Werte der Variablen.

Ich scheine mich zu erinnern, dass es einige Fortschritte bei der Erstellung eines C/C++ - Jits in Clang unter dem Namen libclang gab.

2
dan_waterworth