Compilateur JIT par rapport aux compilateurs hors ligne [c#]


Answers

Oui, les compilateurs JIT peuvent produire un code machine plus rapide optimisé pour l'environnement actuel. Mais pratiquement les programmes VM sont plus lents que les programmes natifs parce que JITing lui-même consomme du temps (plus d'Optimisation == plus de temps), et pour de nombreuses méthodes, JIT les consomme peut-être plus de temps que de les exécuter. Et c'est pourquoi GAC est introduit dans .NET

Un effet secondaire pour JITing est la consommation de mémoire importante. Cependant, cela n'est pas lié à la vitesse de calcul, cela peut ralentir l'exécution de tout le programme, car une grande consommation de mémoire augmente la probabilité que votre code soit renvoyé vers le stockage secondaire.

Excusez-moi pour mon mauvais anglais.

Question

Existe-t-il des scénarios où le compilateur JIT est plus rapide que d'autres compilateurs comme C ++?

Pensez-vous que dans le futur, le compilateur JIT verra juste des optimisations mineures, des fonctionnalités mais suivra une performance similaire, ou y aura-t-il des percées qui le rendront infiniment supérieur aux autres compilateurs?

Il semble que le paradigme multi-noyau soit prometteur, mais ce n'est pas une magie universelle.

Des idées?




Fondamentalement, les compilateurs JIT ont une chance de profiler réellement l'application en cours d'exécution, et faire quelques allusions basées sur cette information. Les compilateurs "hors ligne" ne pourront pas déterminer à quelle fréquence une branche saute et à quelle fréquence elle tombe, sans insérer de code spécial, demander au dev de lancer le programme, le mettre à l'épreuve et le recompiler.

Pourquoi est-ce important?

//code before
if(errorCondition)
{
  //error handling
}
//code after

Se convertit en quelque chose comme:

//code before
Branch if not error to Code After
//error handling
Code After:
//Code After

Et les processeurs x86 ne prévoient pas de saut conditionnel en l'absence d'informations de l'unité de prédiction de branchement. Cela signifie qu'il prédit le code de gestion des erreurs à exécuter et que le processeur doit vider le pipeline lorsqu'il constate que la condition d'erreur ne s'est pas produite.

Un compilateur JIT pourrait voir cela, et insérer un indice pour la branche, de sorte que le CPU prédireait dans la bonne direction. Certes, les compilateurs hors ligne peuvent structurer le code d'une manière qui évite l'erreur, mais si vous avez besoin de regarder l'assemblage, vous n'aimerez peut-être pas sauter partout ...




Beaucoup de gens ont répondu que je skippais (peut-être que j'ai la mauvaise extrémité du bâton) mais pour moi ils sont deux choses différentes:

AFAIK il n'y a rien qui vous empêche JIT compilé c ++ par exemple projet de code machine Dynamo JIT'ed:

http://arstechnica.com/reviews/1q00/dynamo/dynamo-1.html

Et il a effectivement apporté des améliorations de vitesse dans certaines circonstances.

Compiler du code, dans le sens d'un compilateur c ++, signifie prendre du code écrit dans une langue et le transformer en un ensemble d'instructions (ou dans certains cas une autre langue à recompiler) qui peut être exécutée par un type de périphérique logique.

par exemple c ++ compiler en assembly (je pense ;-) ou c # compiler en IL ou Java compiler en byte code

JIT est un processus qui se produit pendant l'exécution. La machine qui exécute le code l'analyse pour voir si elle peut l'améliorer. Java et C # sont capables de faire usage des deux car le compilateur prépare les commandes pour la machine virtuelle, et la machine virtuelle a l'occasion au moins d'en utiliser une autre pour l'optimiser.

Certains programmes ne sont pas compilés, ils sont interprétés, ce qui signifie que la machine qui les exécute lit le code exact que vous avez écrit. Ces machines ont l'opportunité de faire du JIT, mais rappelez-vous qu'elles peuvent aussi être compilées statiquement, potentiellement être un fournisseur tiers d'une manière que le concepteur original de la langue n'a jamais voulu.

Donc, pour répondre à votre question, je ne pense pas que JIT va remplacer les compilateurs statiques. Je pense qu'il y aura toujours (aussi longtemps qu'il y aura de la programmation) un endroit pour prendre une représentation d'un programme et le convertir en un ensemble d'instructions pour une machine quelconque. (optimisant potentiellement pendant qu'il le fait)

Cependant, je pense que JIT pourrait devenir une plus grande partie de l'histoire, au fur et à mesure que le temps d'exécution Java et le temps d'exécution de .net évolueront. Je suis sûr que le JIT s'améliorera. aussi, de sorte que tout ce que fait votre processeur soit ré-optimisé en fonction de l'environnement d'exécution.




Un avantage de JITing qui n'a pas encore été mentionné est qu'il est possible pour un programme de définir un nombre infini de types génériques. Par exemple:

interface IGenericAction { bool Act<T>(); }

struct Blah<T>
{
  public static void ActUpon(IGenericAction action)
  {
     if (action.Act<T>())
       Blah<Blah<T>>.ActUpon(action);
  }
}

Appeler Blah<Int32>.ActUpon(act) appellera act.Act<Int32>() . Si cette méthode renvoie true, elle appellera Blah<Blah<Int32>>.ActUpon(act) , qui appellera à son tour act.Act<Blah<Int32>>() . Si cela retourne vrai, plus d'appels seront effectués avec un type encore plus profondément imbriqué. Générer du code pour toutes les méthodes d' ActUpon qui pourraient être appelées serait impossible, mais heureusement ce n'est pas nécessaire. Les types n'ont pas besoin d'être générés avant d'être utilisés. Si l' action<Blah<...50 levels deep...>>.Act() renvoie false, puis Blah<Blah<...50 levels deep...>>.ActUpon n'appellera pas Blah<Blah<...51 levels deep...>>.ActUpon et le dernier type n'aura pas besoin d'être créé.




Les compilateurs JIT ont plus de données qu'ils peuvent utiliser pour influencer les optimisations. Bien sûr, quelqu'un doit écrire du code pour utiliser ces données, donc ce n'est pas si simple que cela.