Sortie de LLVM 2.6

Posté par  (site web personnel) . Modéré par Mouns.
Étiquettes :
36
25
oct.
2009
Technologie
LLVM, pour Low Level Virtual Machine, est un niveau d'abstraction pouvant se rapprocher d'une machine virtuelle permettant de lancer des programmes compilés en une représentation intermédiaire (LLVM bytecode), ainsi que de générer directement des binaires natifs pouvant être lancés sans LLVM.

LLVM est entre autres utilisé par Gallium 3D[en], une infrastructure de pilotes de carte graphique, pour compiler à la volée les shaders utilisés par les cartes graphiques, et ainsi les optimiser. LLVM est également utilisé par le projet Clang, un compilateur C, C++, Objective-C et Objective-C++ libre faisant concurrence à GCC, et en partie développé par Apple. Notez que bien que le support du C par Clang soit tout à fait correct, son support du C++ laisse encore quelque peu à désirer.

Le 23 octobre 2009, la version 2.6 de LLVM est sortie. Cette version apporte pas mal de nouveautés depuis la version 2.5 sortie le 2 mars 2009, version qui a fait l'objet d'une dépêche. Le détail de ces nouveautés se trouve dans la suite de la dépêche. Les principales nouveautés de cette version sont disponibles sur la page des nouveautés[en] sur le site de LLVM. Voici une brève liste des points les plus importants, reprise de cette page et traduite :
  • De nouveaux sous-projets sont venus s'ajouter au projet LLVM, aux côtés de Clang et des différentes bibliothèques ;
  • Les informations de débogage sont maintenant enregistrées dans les fichiers générés, même quand les optimisations sont activées. Ainsi, GDB pourra mieux déboguer un programme compilé avec Clang et LLVM, et afficher plus d'informations ;
  • De nouvelles architectures sont supportées pour la génération de code binaire natif : MSP430, SystemZ et BlackFin ;
  • Arrivée du support du lieur Gold, qui permet d'appliquer aux exécutables des optimisations à la liaison, ce qui permet par exemple de détecter les fonctions qui ne sont pas appelées, les fonctions appelées une fois, celles qui retournent toujours le même résultat, etc. ;
  • Ceci va plaire aux possesseurs de Dual Core ou Quand Core : LLVM peut maintenant en profiter pour opérer ses optimisations sur plusieurs cœurs à la fois ;
  • Des méta-données peuvent être incluses dans le fichier bytecode généré.
Le langage LLVM lui-même, LLVM-IR (pour LLVM Intermediate Representation) a lui aussi gagné en fonctionnalités, détaillées sur cette même page.

Toujours sur cette page, on peut constater une impressionnante liste de changements sur les autres parties de LLVM : génération de binaires pour différentes architectures, optimisations plus poussées, améliorations des bibliothèques partagées pour usage dans des programmes externes et encore quelques détails.

Cette version semble donc particulièrement intéressante, surtout que Clang lui-même évolue très vite, notamment du côté du C++ ainsi que je l'avais détaillé dans un précédent journal. Espérons que ça continue comme cela. C'est agréable de voir un nouveau compilateur, utilisant des concepts très intéressants, naître sous nos yeux et devenir de plus en plus avancé.

Aller plus loin

  • # BarCamp LLVM le 20 novembre a la Cantine

    Posté par  (site web personnel) . Évalué à 9.

    Un barcamp (journee de mini-conferences informelles pendant laquelle tous les participants sont invites a proposer des presentations, ateliers ou sujets de discussions) est organise vendredi 20 novembre a La Cantine a Paris :

    http://barcamp.org/LLVM-BarCamp-Paris

    N'hesitez pas a vous inscrire et a proposer des sujets sur le wiki. Les propositions de participation sur des sujets connexes (programmation GPU, OpenCL, JIT compiling ...) sont egalement les bienvenues.
  • # Debug avec le JIT

    Posté par  (site web personnel) . Évalué à 10.

    Le problème d'un compilateur à la volée est que c'est difficile à déboguer. La dernière version d'Unladen Swallow (qui utilise LLVM), la 2009Q3, inclut de symbole de debug pour gdb 7.0 :

    "The Unladen Swallow team added support to gdb 7.0 that allow JIT compilers to emit DWARF debugging information so that gdb can function properly in the presence of JIT-compiled code. This interface should be sufficiently generic that any JIT compiler can take advantage of it."
    http://code.google.com/p/unladen-swallow/wiki/Release2009Q3

    Ça évite d'avoir juste des "???" dans gdb ;-)

    La modif a été faite directement dans LLVM :
    http://llvm.org/docs/DebuggingJITedCode.html
  • # Ceci n'est pas une critique...

    Posté par  (site web personnel) . Évalué à 3.

    J'ai beau me triturer les méninges, je n'arrive pas à voir la plus-value par rapport à un autre compilateur, au hasard gcc...

    Merci de m'éclairer car je pense être dans l'erreur vu la quantité de news LLVM qui circule (et aussi le fait que patrick_g s'y intéresse :))

    Domo arigato !
    • [^] # Re: Ceci n'est pas une critique...

      Posté par  (site web personnel) . Évalué à 7.

      LLVM est sous licence BSD, est plus jeune (ne traine pas du vieux code depuis 1985 comme gcc), sait faire des optimisations dont GCC est incapable (parce que GCC est difficile à modifier, plus gros, plus complexe), possède un compilateur à la volée (JIT). Il me semble que LLVM est plus générique que GCC (gère plus de langages et des langages plus variés) : LLVM est par exemple utilisé pour compiler les shaders pour GPU avec Gallium ou bien pour compiler du Python à la volée.

      J'ai l'impression que LLVM est plus conçu comme une bibliothèque intégrable à un projet existant qu'un programme en ligne de commande.
      • [^] # Re: Ceci n'est pas une critique...

        Posté par  (site web personnel) . Évalué à 6.

        >>> l me semble que LLVM est plus générique que GCC (gère plus de langages et des langages plus variés)

        Hum en tous cas le front end gère moins de langage que GCC puisque LLVM est obligé d'utiliser GCC pour analyser certains langages (C++ au hasard).
      • [^] # Re: Ceci n'est pas une critique...

        Posté par  . Évalué à 8.

        >sait faire des optimisations dont GCC est incapable

        J'ai l'impression d'entendre un homme politique parlé la..
        Techniquement ce que tu dis est vrai, mais cette tournure de phrase est trompeuse: ok LLVM est capable de faire des optimisations que GCC ne peut pas faire, mais la vrai question est: lequel optimise le mieux?

        La dernière fois que j'ai vu un comparatif (qui n'était pas avec la version 2.6 pour LLVM bien sûr) c'était GCC qui générait des exécutables plus performants.


        • [^] # Re: Ceci n'est pas une critique...

          Posté par  . Évalué à 6.

          Llvm ne produit généralement pas du meilleur code que gcc. Par contre le code est plus moderne (par exemple dans les representations internes), plus modulaire (permet de l'utiliser en librairie, pour du JIT, etc.), et un peu de concurrence ne fait pas de mal.
          • [^] # Re: Ceci n'est pas une critique...

            Posté par  . Évalué à 4.

            Techniquement, LLVM permet bien plus facilement l'injection de nouvelles transformations dans le processus de compilation. Du coup, il est mieux fichu (pour le moment) que GCC car il permet de tester directement de nouvelles idées sans avoir un compilateur de recherche à portée de main (c'est généralement comme ça que les chercheurs voient qu'une idée est bonne : en l'implémentant dans leur compilateur maison -- sauf que tout le monde n'en a pas).

            Mais comme il a été dit dans un journal d'ailleurs, GCC est sur le point d'avoir les plugins autorisés. Et ça, c'est grâce à LLVM, car il n'en était pas question au départ.

            Enfin il y a aussi la licence de GCC qui gêne certains (oui, ceux qui voudraient bien l'améliorer sans rien reverser à la communauté, ou ceux qui veulent utiliser le front-end pour leur compilateur, etc.)
    • [^] # Re: Ceci n'est pas une critique...

      Posté par  (site web personnel) . Évalué à 4.

      >>> Merci de m'éclairer car je pense être dans l'erreur vu la quantité de news LLVM qui circule (et aussi le fait que patrick_g s'y intéresse :))

      Encore une fois je suis juste un rédacteur de news et pas du tout un spécialiste ou même un développeur.
    • [^] # Re: Ceci n'est pas une critique...

      Posté par  . Évalué à 7.

      J'ai beau me triturer les méninges, je n'arrive pas à voir la plus-value par rapport à un autre compilateur, au hasard gcc...

      L'architecture de LLVM en fait un outil plus versatile. On peut en effet n'utiliser qu'un ensemble des briques de LLVM sans les autres de façon très aisée. A titre d'exemple il y a des projets :
      - qui se servent de LLVM pour faire de la compilation JIT (chose impossible, il me semble, avec GCC)
      - qui se servent de clang (le frontend pour le C, C++, Objective-C et Objective-C++), pour faire de l'analyse statique de code (chose qui est difficile actuellement avec gcc, qui devrait être un peu plus simple avec le mécanisme de plugin)

      Le point important est qu'on peut utiliser LLVM comme une bibliothèque en ne récupérant que les composants nécessaires, contrairement à gcc qui ne permettra que de se greffer sous forme de plugins.

      Au niveau de l'utilisateur, clang permet, selon le site (cf http://clang.llvm.org/features.html#enduser )
      - de meilleurs messages de diagnostique
      - une moins grande consommation mémoire
      - une plus grande rapidité d'analyse du code.


      Étienne
  • # Comparaison avec GCC

    Posté par  (site web personnel) . Évalué à 6.

    J'ai trouvé une comparaison avec GCC 4.5 (qui n'est pas encore sorti) sur ces slides issues du projet LLVM : http://llvm.org/devmtg/2009-10/Sands_LLVMGCCPlugin.pdf

    Le test se fait sur le logiciel Sqlite3 avec l'optimisation -O3

    Rapidité de compilation :

    LLVM/Clang : 6.3 secondes
    GCC 4.5 : 15.5 secondes

    Victoire sans appel de LLVM/Clang donc.

    Rapidité du logiciel compilé :

    LLVM/Clang : 5.4 secondes
    GCC 4.5 : 4.6 secondes

    Le résultat s'inverse et c'est GCC qui remporte la palme de la meilleure optimisation.
    • [^] # Re: Comparaison avec GCC

      Posté par  (site web personnel) . Évalué à 3.

      faudrait voir sur de nombreux exemple pour en déduire de quoi...

      www.solutions-norenda.com

      • [^] # Re: Comparaison avec GCC

        Posté par  . Évalué à 4.

        bon qui s'amuse à faire un emerge world
      • [^] # Re: Comparaison avec GCC

        Posté par  (site web personnel) . Évalué à 8.

        C'est en effet très dépendant du code, je vous donne les résultats de mes tests entre GCC 4.4 et LLVM+CLang 2.6. Pour les deux j'ai passé pas mal de temps à chercher les bonnes options pour obtenir les meilleurs perfs.

        Sur mon programme de Go en C99 pur qui contient beaucoup de manipulation de tableaux d'entiers, CLang est environ 20% plus rapide.

        Sur mes programme de calcul scientifique (apprentissage de modèle CRF) avec beaucoup de caculs en flotants double précision. La version qui utilise du code vectoriséen sse2 (intrinsics plus opération sur des __m128d du genre a + b * c) est 24% plus rapide avec CLang ; par contre la version en C99 pur sans utiliser sse2 (juste i686) est 29% plus rapide avec GCC.
        Il semble que CLang à plus de mal avec l'unitée de calcul flotant des x86 mais s'en sort très bien quand on lui permet d'utiliser les sse.

        Au niveau temps de compilation, je peut pas vraiment dire, même si ce sont des programme très complexes, ils ne dépassent pas les quelques miliers de lignes de code et sont donc très rapide à compiler même avec toutes les options au max.

        J'ai dans ma TODO list de pousser un peu plus loin pour voir ce qui fait vraiment la différence ; mais ça reste une entrée de plus dans la liste.. donc je ne sais pas quand j'en aurais vraiment le temps.

        Ce qu'il faut bien voir avec LLVM+CLang c'est pas vraiment les perfs actuelles mais surtout le fait que c'est est framework propre et moderne pour la compilation qui est très agréable à utiliser. Donc même si actuellement il n'est pas toujours plus rapide que GCC, il à de bonne chances de représenter l'avenir.
        Implémenter de nouvelle passe d'optimisation dans LLVM est infiniment plus facile et plus agréable que dans GCC ; il est donc probable que, progressivement, les nouvelles techniques d'optimisation soient d'abord intégrées dans LLVM avant GCC.
        • [^] # Re: Comparaison avec GCC

          Posté par  (site web personnel) . Évalué à 2.

          Concernant la différence de performance en flottant, n'est-ce pas encore une histoire d'option "--fast-math" caché ? Si LLVM ne tronque pas les résultats x87 sur 64 bits au lieu de 80, la différence de perf peut être pas mal. En général, les personnes qui lisent l'assembleur générés par gcc disent qu'il est débile car il rajoute plein de load/store parfaitement inutile. Or, c'est la manière de tronquer les bits en trop. Si les programmes sont petits, cela peut être très instructif de lire la différence au niveau assembleur.

          "La première sécurité est la liberté"

          • [^] # Re: Comparaison avec GCC

            Posté par  (site web personnel) . Évalué à 4.

            Les deux version sont compilées sans fast-math, vu les calculs il n'y a de toute façon pas le choix, il faut la précision maximale et c'est déjà parfois limite (un forward/backward sur des séquences un peu longue demande de faire très attention au calcul pour ne pas avoir de probèmes). En plus dans ce cas, l'avantage va nettement à GCC.

            C'est même ce problème qui fait que j'ai codé à la fois une version sse2 et une version classique, le sse2 à des registres vectoriels sur 64bits par éléments. Le programme normal choisit, en fonction des conditions, s'il peut utiliser la version sse2 ou s'il doit se rabatre sur la version classique car il risque d'avoir des problèmes.

            Qu'il soit compilé avec GCC ou CLang, le programme donne exactement le même résultat au bit près, donc à priori ils font bien le même calcul. Un accord aussi parfait entre les deux m'a même étonné... la preuve que le standard IEEE sur les flotants est pas mal foutu.

            Pour ce qui est du code ASM, j'ai beaucop exploré celui de la version sse2 car 95% des séquences sont calculées avec, donc celui là j'ai passé pas mal de temps à l'optimiser, et donc à comprendre le code que me génerait chacun des compilos en fonction de ce que je leur donnait ; par contre la version classique représente trop peu du temps d'éxecution pour que ça vaille le coup de s'en préoccuper. J'ai juste vérifié que les deux compilos utilisait bien la pile flottante classique et pas le sse pour être sur mais c'est tout.

            C'est un gros casse tête ces problèmes de précision et à mon avis ces ce qui limite l'utilisation des instruction SIMD dans le calcul scientifique. Avec 80bits de précision, on réussit souvent à s'en sortir sans utilisé de bibliothèque spécialisées. Avec 64 bits c'est un vrai casse-tête.
          • [^] # Re: Comparaison avec GCC

            Posté par  . Évalué à 2.

            >En général, les personnes qui lisent l'assembleur générés par gcc disent qu'il est débile car il rajoute plein de load/store parfaitement inutile.

            Euh, pourquoi tronquer les résultats?
            Avoir des bits significatifs en moins c'est mal ok, mais en trop, à part dans des cas très particuliers, je ne vois pas ou est le problème, j'espère que ce n'est pas activé par défaut..
            • [^] # Re: Comparaison avec GCC

              Posté par  (site web personnel) . Évalué à 4.

              si.

              En fait, intel calcul toujours sur 80 bits, mais AMD sur 64. Résultat 2 machines peuvent te donner 2 résultats différents sur le même calcul ! Bref, les utilisateurs ne veulent pas de ça.

              "La première sécurité est la liberté"

        • [^] # Re: Comparaison avec GCC

          Posté par  (site web personnel) . Évalué à 1.

          A propos de CRF en C, tu connais CRFsuite ? http://www.chokkan.org/software/crfsuite/
          • [^] # Re: Comparaison avec GCC

            Posté par  (site web personnel) . Évalué à 4.

            Je connais et il est bon pour ce pourquoi il est prévu, c'est à dire une version très simple des CRF linéaires. Les features bigrammes ne peuvent dépendre que des éttiquettes et pas des autres données d'entrée, ce qui est relativement limité mais permet beaucoup d'optimisation du code.
            Donc si ce modèle suffit il fait bien le boulot, mais ces pas notre cas... Et le problème c'est justement qu'il est très lié à son modèle ce qui rend difficile de le modifier pour en faire autre chose.

            Mon objectif était d'implémenter un nouvel algorithme d'optimisation des CRFs qui optimise le modèle coordonées par coordonées. CRFSuite implémente le gradient classique à l'aide de LBFGS qui optimise tout le modèle à chaque itérations avec toutes les séquences d'entrées ainsi qui le SGD qui optimise tout le modèle avec une seule séquence. Notre approche est d'optimiser une seule coordonée à la fois mais avec toutes les séquence ou cette coordonée est active. On a soumit un papier sur l'algorithme, si le sujet t'intéresse tu peut trouver un preprint ici http://oniros.org/papers/sokolovska09jstsp.pdf .

            Il optimise aussi les CRF linéaire mais à l'inverse de CRFSuite il permet d'utiliser des features bigrammes aussi riches que les features unigrammes, ce qui permet de construire des modèles bien plus performants. (mais aussi bien plus long à entrainer...)
            La version du programme utilisée quand on à écrit le papier n'utilisait pas le sse, donc les comparaison de vitesse avec CRF++ et CRFsgd sont équitable.

            Pour l'instant je travail au nettoyage du code car si l'algorithme en lui même en plutôt propre, c'est pas vraiment le cas de la partie lecture des données et génération des features... J'espère pouvoir le publier bientôt sous licence libre, je ferais un journal au moment ou ce sera près, mais s'il y en à que ça intéresse, n'hésitez pas à me contacter directement.
            • [^] # Re: Comparaison avec GCC

              Posté par  (site web personnel) . Évalué à 2.

              Ton algo me fait penser a Stochastic Coordinate Descent:
              http://ttic.uchicago.edu/~tewari/code/scd/

              Aussi, pour vos features, est ce que vous utilisez le "Hashing Trick" ? Ou vous maintenez une representation explicite du dictionnaire de token (char[]) vers feature_id (long long) en memoire ?

              http://hunch.net/~jl/projects/hash_reps/index.html

              J'imprime ton papier pour le lire ce soir, ca m'interesse d'etre tenu au courant si vous publiez votre code source sous une license libre (message perso sur linuxfr, DM sur http://twitter.com/ogrisel, ou email olivier.grisel at ensta dot org).
              • [^] # Re: Comparaison avec GCC

                Posté par  (site web personnel) . Évalué à 1.

                Désolé pour la réponse un peu tardive.
                Je ne connaissait pas ce papier, j'ai regardé mais pas encore détaillé. En effet il y a des similaritées dans le sens ou c'est aussi une approche d'optimisation coordonées par coordonées, mais leur approche est stochastique. Il est maintenant dans ma liste de papiers à étudier en détails.

                Pour ce qui est du hashing des features, la réponse est non. Le hashing à deux avantages :
                -réduire la taille du modèle final en regroupant les features en paquets plus ou moins aléatoire, dans notre cas la régularization L1 permet déjà de réduire la taille du modèle en supprimant les features qui ne sont pas informative, donc au moins théoriquement c'est plus éfficace ;
                - réduire la taille du modèle à l'apprentissage, et donc accélérer l'apprentissage. Ça pourrait accélérer l'apprentissage de notre modèle, mais ça peut aurrait des interaction avec la norme L1. Ces interaction ne sont pas forcément génantes en pratique mais il faudrait faire des expérimentation pour en être sur. Pour l'instant en tout cas, on reste sur une gestion classique pour pouvoir évaluer objectivement l'algo.

                De plus le hashing n'accélère pas tant que ça l'apprentissage, aussi bien le mapping feature->id que la mise à jour des poids des features sont néligeables par rapport au temps passé au calcule des espérance pour chaque séquences (qui représente en gros 92% du temps d'aprentisage dans notre algo) et il à l'inconvénient que ça fait encore un paramètre de plus à regler. (le nombre de features final)
                Il a l'avantage par contre d'être bien plus simple à coder.

                J'ai noté ton mail, je te préviens dès que le code est libre.
    • [^] # Re: Comparaison avec GCC

      Posté par  . Évalué à 4.

      Pour un developpeur les temps de compilation a mesurer seraient aussi avec '-O0 -g' pour les versions intermédiaires..

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.