44 votes

Pourquoi le moteur d'exécution LLVM est-il plus rapide que le code compilé?

J'ai un compilateur qui vise LLVM, et je fournir deux façons d'exécuter le code:

  1. Exécuter automatiquement. Ce mode compile le code de LLVM et utilise le ExecutionEngine JIT compiler en code machine sur-le-champ et de l'exécuter sans jamais générer un fichier de sortie.
  2. Le compiler et l'exécuter séparément. Ce mode génère un LLVM .bc fichier, que j'optimiser manuellement (avec opt), les compiler en natif de l'assemblée (avec llc) compiler en code machine et un lien (avec gcc), et de l'exécuter.

Je m'attendais à une approche #2 pour être plus rapide que l'approche #1, ou au moins à la même vitesse, mais l'exécution de quelques tests de vitesse, je suis surpris de constater que le n ° 2 de manière cohérente fonctionne environ deux fois plus lent. C'est une énorme différence de vitesse.

Les deux cas sont en cours d'exécution de la même LLVM code source. Avec l'approche n ° 1, je n'ai pas encore pris la peine de courir tout LLVM optimisation de passe (c'est pourquoi je m'attendais à être plus lent). Avec l'approche n ° 2, je suis en cours d'exécution opt avec -std-compile-opts et llc avec -O3, pour maximiser l'optimisation, mais il n'est pas d'obtenir n'importe où près de #1. Voici un exemple d'exécution du même programme:

  • #1 sans optimisation: 11.833 s
  • #2 sans optimisation: 22.262 s
  • #2 avec optimisation (-std-compile-opts et -O3): 18.823 s

Est le ExecutionEngine de faire quelque chose de spécial que je ne le sais pas? Est-il possible pour moi d'optimiser le code compilé pour obtenir la même performance que le ExecutionEngine JIT?

30voto

Michael Dillon Points 18741

Il est normal pour une machine virtuelle avec JIT pour exécuter certaines applications plus rapide que pour une application compilée. C'est parce que d'une machine virtuelle avec JIT, c'est comme un simulateur qui simule un ordinateur virtuel, et gère également un compilateur en temps réel. Parce que les deux tâches sont intégrées dans la VM avec JIT, le simulateur machine peut fournir des informations pour le compilateur, de sorte que le code peut être recompilé à fonctionner plus efficacement. Les informations qu'il fournit n'est pas disponible de manière statique du code compilé.

Cet effet a également été observé avec les machines virtuelles Java et Python PyPy VM, entre autres.

14voto

Un autre problème est l'alignement de code et d'autres optimisations. Aujourd'hui, les cpu sont tellement complexes qu'il est difficile de prédire quelles sont les techniques qui vont plus vite au résultat de l'exécution de finale binaire.

Comme un exemple concret, prenons l'exemple de Google Native Client - je veux dire d'origine nacl compilation approche, pas involing LLVM (cause, autant que je sache, il n'est actuellement la direction sur le soutien à la fois "nativeclient" et "LLVM bitcode"(modyfied) du code).

Comme vous pouvez le voir sur les présentations (découvrez youtube.com) ou dans les documents, à l'instar de cette Native Client: Un bac à sable pour Portable, non approuvé x86 Code Natif, même leur alignement technique rend le code taille plus grande, dans certains cas, un tel alignement des instructions (par exemple avec noops) donne de meilleurs cache frapper.

L'alignement des instructions avec noops et l'instruction de la réorganisation en calcul parallèle, et ici, il montre que c'est l'impact.

J'espère que cette réponse donne une idée de combien de circonstances peuvent influencer sur le code de la vitesse d'exécution, et qui sont beaucoup de raisons possibles pour les différents morceaux de code, et chacun d'eux a besoin d'enquête. Nevermore, c'est intéressant ce sujet, donc Si vous trouvez plus de détails, ne pas hestitate à remodifier votre réponse et laissez-nous savoir dans les "Post-Scriptorium", qu'avez-vous trouvé de plus :). (Peut-être un lien vers livre blanc/devblog avec les nouveaux résultats :) ). Les repères sont toujours les bienvenus prendre un coup d'oeil : http://llvm.org/OpenProjects.html#benchmark .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X