web-dev-qa-db-fra.com

Compilateur JIT pour C, C ++ et autres

Existe-t-il un compilateur juste à temps pour les langages compilés, tels que C et C++? (Les premiers noms qui me viennent à l'esprit sont Clang et LLVM! Mais je ne pense pas qu'ils le soutiennent actuellement.)

Explication:

Je pense que le logiciel pourrait bénéficier de la rétroaction du profilage d'exécution et d'une recompilation agressive optimisée des hotspots au moment de l'exécution, même pour les langages compilés vers la machine comme C et C++.

L'optimisation guidée par le profil fait un travail similaire, mais avec la différence, un JIT serait plus flexible dans différents environnements. Dans PGO, vous exécutez votre binaire avant de le libérer. Après l'avoir publié, il n'utiliserait aucun retour d'environnement/entrée collecté lors de l'exécution. Donc, si le modèle d'entrée est modifié, il s'agit d'une pénalité de performance. Mais JIT fonctionne bien même dans ces conditions.

Cependant, je pense qu'il est controversé de savoir si l'avantage de performance de compilation JIT l'emporte sur ses propres frais généraux.

33
Ebrahim Mohammadi

[Voir l'historique des modifications pour une réponse assez différente qui est maintenant fondamentalement obsolète.]

Oui, il existe quelques compilateurs JIT pour C et/ou C++.

CLing (comme vous pouvez le deviner dans le jeu) est basé sur Clang/LLVM. Il agit comme un interprète. Autrement dit, vous lui donnez du code source, donnez une commande pour qu'il s'exécute et il s'exécute. L'accent est mis ici principalement sur la commodité et la compilation rapide, et non sur l'optimisation maximale. En tant que tel, bien que techniquement une réponse à la question elle-même, cela ne correspond pas vraiment à l'intention du PO.

Une autre possibilité est NativeJIT . Cela correspond à la question un peu différemment. En particulier, il n'accepte pas le code source C ou C++, le compile et l'exécute. Il s'agit plutôt d'un petit compilateur que vous pouvez compiler dans votre programme C++. Il accepte une expression qui est essentiellement exprimée sous la forme d'un EDSL à l'intérieur de votre programme C++, et génère du code machine réel à partir de cela, que vous pouvez ensuite exécuter. Cela correspond beaucoup mieux à un cadre où vous pouvez compiler la plupart de votre programme avec un compilateur normal, mais avez quelques expressions que vous ne connaîtrez pas avant l'exécution, que vous souhaitez exécuter avec quelque chose qui approche de la vitesse d'exécution optimale.

Quant à l'intention apparente de la question d'origine, je pense que le point de base de ma réponse d'origine est toujours valable: alors qu'un compilateur JIT peut s'adapter à des choses telles que les données qui varie d'une exécution à l'autre, voire variant dynamiquement au cours d'une même exécution, la réalité est que cela ne fait que peu de différence au moins en règle générale. Dans la plupart des cas, l'exécution d'un compilateur au moment de l'exécution signifie que vous devez renoncer à un peu d'optimisation, donc le meilleur que vous espérez habituellement est qu'il est presque aussi rapide qu'un compilateur conventionnel produirait.

Bien qu'il soit possible de postuler des situations où les informations disponibles pour un compilateur JIT pourraient lui permettre de générer un code sensiblement meilleur qu'un compilateur conventionnel, des exemples de cela se produisent dans la pratique semblent assez inhabituels (et dans la plupart des cas où j'ai pu vérifier que cela se produisait, c'était vraiment dû à un problème dans le code source, pas avec le modèle de compilation statique).

33
Jerry Coffin

Oui, il existe des compilateurs JIT pour C++. Du point de vue de la performance, je pense que l'optimisation guidée par le profil (PGO) est toujours supérieure.

Cependant, cela ne signifie pas que la compilation JIT n'est pas encore utilisée dans la pratique. Par exemple, Apple utilise LLVM comme JIT pour leur pipeline OpenGL. C'est un domaine où vous disposez de beaucoup plus d'informations à l'exécution, qui peuvent être utilisées pour supprimer beaucoup de code mort.

Une autre application intéressante de JIT est Cling, un interpréteur C++ interactif basé sur LLVM et Clang: https://root.cern.ch/cling

Voici un exemple de session:

[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

Ce n'est pas un projet de jouet, mais il est en fait utilisé au CERN, par exemple, pour développer le code du Large Hadron Collider.

11
Philipp Claßen

C++/CLI est supprimé. Certes, C++/CLI n'est pas pas C++ mais il est assez proche. Cela dit, le JIT de Microsoft ne fait pas les types d'optimisations basés sur le comportement à l'exécution super intelligents/mignons dont vous parlez, du moins pas à ma connaissance. Donc ça n'aide vraiment pas.

http://nestedvm.ibex.org/ transforme MIPS en Java bytecode qui serait ensuite jitted. Le problème avec cette approche de votre question est que vous jetez une grande partie des informations utiles au moment où il arrive au JIT.

7
Logan Capaldo

Tout d'abord, je suppose que vous voudriez un jit de traçage plutôt qu'un jit de méthode.

La meilleure approche à adopter serait de compiler le code en llvm IR, puis d'ajouter du code de traçage, avant de produire un exécutable natif. Une fois qu'un bloc de code est suffisamment bien utilisé et une fois que suffisamment d'informations sur les valeurs (pas les types comme dans les langages dynamiques) de variables ont été collectées, le code peut être recompilé (à partir de l'IR) avec des gardes basés sur les valeurs des variables.

Je crois me souvenir qu'il y a eu des progrès sur la création d'un jit c/c ++ dans clang sous le nom libclang.

2
dan_waterworth