6
votes

Juste dans la compilation temporelle toujours plus rapide?

Salutations à tous les concepteurs compilateurs ici sur le débordement de la pile.

Je travaille actuellement sur un projet, qui se concentre sur le développement d'une nouvelle langue de script à utiliser avec l'informatique hautes performances. Le code source est d'abord compilé dans une représentation du code octet. Le code d'octet est ensuite chargé par le temps d'exécution, qui effectue des optimisations agressives (et éventuellement de consommation de temps) (qui vont beaucoup plus loin que ce que les compilateurs «à l'avance» font, après tout ce qui est tout ce qui est tout ce que tout est tout ce qui est tout ce qui est tout ce qui est tout ce qui est tout ce qui est tout ce que tout est tout ce que tout est tout ce qui est tout ce qui est tout ce qui est tout ce qui est tout le point de la projet). N'oubliez pas que le résultat de ce processus est toujours du code octet.

Le code octet est ensuite exécuté sur une machine virtuelle. Actuellement, cette machine virtuelle est implémentée à l'aide d'une table de saut simple et d'une pompe à message. La machine virtuelle fonctionne sur le code octet avec un pointeur, charge l'instruction sous le pointeur, lève un gestionnaire d'instructions dans la table de saut et saute dessus. Le gestionnaire d'instructions effectue les actions appropriées et renvoie enfin le contrôle à la boucle de message. Le pointeur d'instructions de la machine virtuelle est incrémenté et tout le processus recommence. La performance que je peux réaliser avec cette approche est en fait assez étonnante. Bien sûr, le code des manipulateurs d'instructions réelles est à nouveau rajusté à la main.

Maintenant la plupart des environnements d'exécution «professionnels» (comme Java, .NET, etc.) utilisent une compilation juste à temps pour traduire le code d'octet en code natif avant l'exécution. Un VM utilisant un JIT a généralement beaucoup de meilleures performances qu'un interprète code octet. Maintenant, la question est, puisque tout un interprète fait fondamentalement, on charger une instruction et recherchez une cible de saut dans une table de saut (rappelez-vous que le gestionnaire d'instructions lui-même est statiquement compilé dans l'interprète. C'est donc déjà un code natif), l'utilisation de La compilation juste à temps entraîne un gain de performance ou sera-t-il dégrader performance? Je ne peux pas vraiment imaginer la table de saut de l'interprète pour dégrader la performance que beaucoup pour constituer le temps passé à compiler ce code utilisant une jière. Je comprends qu'un jiteur peut effectuer une optimisation supplémentaire sur le code, mais dans mon cas, une optimisation très agressive est déjà effectuée sur le niveau de code octet avant l'exécution. Pensez-vous que je pourrais gagner plus de vitesse en remplaçant l'interprète par un compilateur JIT? Si oui, pourquoi?

Je crois comprendre que la mise en œuvre des approches et de l'analyse comparative fournira la réponse la plus précise à cette question, mais cela ne vaut peut-être pas le moment s'il y a une réponse claire.

Merci.


2 commentaires

Si optimisation très agressif est effectué avant de compiler, je le doute. Dépend de la qualité de vos optimalités.


Principe intéressant pour une thèse de doctorat en informatique. Faites-nous savoir quand les résultats sont publiés.


3 Réponses :


1
votes

JIT peut optimiser théoriquement mieux, car il dispose d'informations non disponibles au moment de la compilation (en particulier sur le comportement typique de l'exécution). Il peut donc par exemple faire une meilleure prédiction des succursales, déployer des boucles si nécessaire, ET.C.

Je suis sûr que votre approche judvable va bien, mais je pense toujours que cela fonctionnerait plutôt pauvre par rapport au code C droit, ne pensez-vous pas?


4 commentaires

Ou en revanche, les frais généraux de la collecte des informations pour que ces optimisations puissent s'avérer plus importants que le code natif puis plus rapide ... La théorie n'est pas vraiment unilatérale - mais vous pouvez obtenir une certaine confiance statistique de expérience dans un domaine problématique particulier.


@Tony: Vous avez raison - souvent plus simple, c'est mieux - mais cela se tourne vers la pratique de la mise en œuvre de VM, et dans de nombreux cas fonctionne bien surtout pour les programmes de longue date.


Vrai. Mais, si les gains étaient vraiment significatifs, alors les langues compilées mettraient dans un code d'instrumentation native et l'alternative déjà compilée et muté elles-mêmes lorsqu'elles sont justifiées (bien entendu nécessiter de faire valoir le système d'exploitation pour permettre aux écritures de pages de mémoire exécutables). Que ce n'est pas généralement poursuivi suggère que les langues de la machine virtuelle exerçaient cela autour de cela plus comme un JAB théorique à leurs homologues précompilés, plutôt que d'être particulièrement efficaces ...? Ou suis-je trop méfiant? ;-)


@Tony: Je ne pense pas que vous suiviez le développement - LLVM est de plus en plus important et a déjà une frontement pour C / C ++ / OBJ-C / FORTRAN ET.C.



4
votes

La réponse réside dans le ratio de la complexité d'instructions-code mono-octet pour sauter des frais généraux de table. Si vous modélisez des opérations de haut niveau telles que les grandes multiplications matricielles, un peu de frais généraux sera insignifiant. Si vous incrémentez un seul entier, alors bien sûr que la table de saut est considérablement affectée. Dans l'ensemble, le solde dépendra de la nature des tâches plus critiques que la langue est utilisée. Si cela est censé être une langue à usage général, il est plus utile que tout soit une surcharge minimale car vous ne savez pas ce qui sera utilisé dans une boucle serrée. Pour quantifier rapidement l'amélioration potentielle, il suffit de comparer certaines boucles imbriquées avec des opérations simples (mais elles ne peuvent être optimisées) par rapport à un programme équivalent C ou C ++.


0 commentaires

2
votes

Lorsque vous utilisez un interprète, le cache de code dans votre processeur met en cache le code d'interprète; pas le code octet (quel peut être mis en cache dans le cache de données). Étant donné que les caches de code sont 2 à 3 fois plus rapides que les caches de données, IIRC; Vous pouvez voir une performance boost si vous vous compilez. De plus, le code Native et réel que vous exécutez est probablement une photo; quelque chose qui peut être évité pour le code chanté.

Tout le reste dépend de l'optimisation du code octet, IMHO.


0 commentaires