• # Mon expérience

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

    Je suis un peu entre-deux au sujet des jumbo builds. Mon expérience me dit que c'est vraiment efficace pour réduire les temps de builds, et j'apprécie quelques effets comme l'idée de ne pas mettre de using namespace à un niveau global. D'un autre côté ça vient avec son lot de surprises que tu as très bien décrites dans ce billet.

    Au niveau des intérêts il y a aussi une réduction des temps de link (i.e. ce n'est pas qu'une question de parsing de headers). Par exemple, dans un code plein de templates, on se retrouve avec ces derniers instanciés avec les mêmes types dans plein de .o, puis le linker doit faire le tri dans tout ça. Avec un unity build il n'y a qu'une seule instanciation du template dans le gros .o, ce qui est plus simple à gérer pour le linker (en plus de ne pas avoir à charger 2000 .o en premier lieu). Je n'ai pas mesuré mais je serais surpris que cela ne soit pas un avantage dans le cadre de LTO aussi.

    Mon top des trucs pénibles serait les #include manquants qui cassent le build incrémental, les fonctions static avec le même nom et la même signature dans plusieurs .cpp, et des #define qu'on retrouve dans plusieurs .cpp aussi. Ce sont les premiers problèmes que je rencontre quand je passe un projet en unity builds.

    Et puis il y a aussi le problème des devs qui s'en fichent pas mal : « Le build est lent ? Achète plus de machines, et des plus grosses. Moi je continue à mettre des using namespace partout et à mettre mes templates sans instanciation explicite. »

    Au final on se retrouve à faire deux builds, un incrémental et un jumbo, pour être sûr que ça fonctionne dans tous les cas, et je me demande si on y gagne vraiment :)

    unity build implies a slight overhead during incremental builds

    Ça dépend du projet ! Même en dev quotidien, en recompilant avec quelques fichiers modifiés ici et là, ça peut aller plus vite de passer par un unity build.

  • # compilateur ?

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

    Pourquoi essayer encore de merger le code au niveau text ? Il ne serait pas plus simple d'avoir un compilo qui lit plusieurs fichiers c à la fois ?

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

    • [^] # Re: compilateur ?

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

      Soit je n'ai pas compris la question, soit c'est déjà ce que font les compilos (ils sont multi-threadés).
      Ça ne réduit pas le temps de build "additionné", car la charge de travail est la même donc c'est plus rapide si tu ne fais rien d'autre mais sur une serveur de compilation qui fait d'autres tâches que la tienne le total revient au même donc pas de machine en moins, alors que les jumbo builds sont la surtout pour réduire la charge de travail et donc réduire le besoin de nombre de machines (avec certes le bonus de compiler plus vite chez toi, parfois, tiens faudrait tester jumbo build qui va être limité en multi threading contre une machine avec beaucoup de threads sans jumbo build, si Julien n'a pas encore fait et est motivé à ajouter ça à son projet).

      • [^] # Re: compilateur ?

        Posté par  (site web personnel) . Évalué à 8. Dernière modification le 05 mai 2023 à 16:36.

        c'est déjà ce que font les compilos (ils sont multi-threadés).

        Es-tu sûr que les compilos soient multi-threadés ? Il me semble que le multi-threading se fait plutôt au niveau de l'outil de build (Make, Ninja) mais que le compilo lui-même est mono-thread.

        Après on paye aussi beaucoup au link. Jumbo build ou pas, le link est un goulot d'étranglement où il faut rassembler l'ensemble des unités de compilation. Et bien que le linker lui-même soit multi-threadé (mold sans aucun doute, lld et gold à voir. GCC semble pouvoir paralléliser LTO au moins), ça reste une très grosse étape.

        • [^] # Re: compilateur ?

          Posté par  (site web personnel) . Évalué à 1. Dernière modification le 05 mai 2023 à 11:46.

          Il me semble que le multi-threading se fait plutôt au niveau de l'outil de build (Make, Ninja) mais que le compilo lui-même est mono-thread.

          Argh, forcément j'ai écrit trop imprécisément et bam… Je voulais préciser que l'ensemble (pour ne pas dire le compilo) lit (et compile) déjà plusieurs fichiers à la fois. Que ce soit le compilo ou l'outil de build est du détail technique peu important (au pire si intérêt un jour pour une optimisation, le compilo aura ça lui-même, mais je ne vois pas l’intérêt en optimisation si le taf est le même).

          Je ne vois pas de gain la (tous les threads sont chargés au max pendant ce moment la).

          le link est un goulot d'étranglement

          Euh, comme tu dis cette partie est déjà multi threadé (et intéressant ici car non parallélisable en dehors, comme pour LTO).

          Perso je vois surtout un besoin de réduire le travail à faire en optimisant les algos, et c'est loin d'être facile à faire (sinon quelqu'un l'aurait déjà fait et payé par par exemple GitHub vu le nombre de compilations de nos jours avec la CI etc :) ).

          • [^] # Re: compilateur ?

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

            sur un compilo tu lis un .c qui include dedans les fichiers qui vont avec, tu produit le .o. Et tu recommences pour chaque .c. Ensuite, tu as assemble tous les .o.

            L'idée, dans le cas d'un Jumbo Build, est de filer tous les fichiers .c concerner en une fois. Ainsi, les include sont lu et parsés une seul fois. Les templates générés une seul fois, et le LTO a beaucoup moins de boulot à faire ensuite.

            Au lieu de concaténer les fichiers ensemble, on les fait lire par le même exe en respectant la sémantique du langage au lieu de se contenter d'inventer un gros fichier.

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

            • [^] # Re: compilateur ?

              Posté par  . Évalué à 2.

              Pour la partie lire une fois les fichiers d'entête tu peux l'obtenir avec la précompilation des entêtes.

              https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

              • [^] # Re: compilateur ?

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

                Est-ce que la limitation de compilation d'un seul .h a été levé ?

                Disons qu'avoir l'AST entier de tout le code pour optimiser à haut niveau peut être intéressant et plus rapide. A l'époque, les .o ont été créer car c'était simplement impossible à faire avec la RAM disponnible.

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

      • [^] # Re: compilateur ?

        Posté par  (Mastodon) . Évalué à 3.

        Soit je n'ai pas compris la question

        Pour moi il propose que les #include n'existent pas et que le compilo prenne en entrée une série de fichiers sources et "mélange" le tout.

        Pour moi c'est une très mauvaise idée, non applicable dans le réel, mais je ne saurais pas expliquer pourquoi :) (donc, on peut en parler !)

        En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

        • [^] # Re: compilateur ?

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

          non, je propose que l'on puisse lancer un
          gcc *.c -o toto.exe

          De la même façon qu'aujourd'hui sauf que le système ne passe pas par les .o intermédiaire ou autre.
          En gros, chaque fichier est gardé en interne sous forme d'AST puis mixer pour faire un gros exe. Le compilateur fonctionnerait en "close world". Cela permet plein d'optimisation.

          J'imagine que go fonctionne comme cela.

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

          • [^] # Re: compilateur ?

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

            Les optimisations sont déjà possibles en activant la "link time optimisation". Dans ce cas, les fichiers .o générés à partir de chaque .c contiennent un dump de l'AST plutôt que du code assembleur généré. Et c'est le linker qui finit le travail.

            Mais ça pose 2 problèmes:

            • Par rapport aux "jumbo builds", on ne gagne pas de temps à re-parser les fichiers .h qui sont inclus plusieurs fois
            • La phase de link prend beaucoup de temps (puisque c'est à ce moment qu'on fait "vraiment" la compilation dans ce cas). Et cette phase est relancée systématiquement à chaque compilation pour le moindre changement d'un seul fichier

            Donc ce n'est pas utile pour un build rapide.

            Une approche intéressante serait peut-être d'avoir un "serveur" de compilation, un outil qui reste chargé en mémoire et qui conserve des morceaux de code précompilés, et qui recompile les parties nécessaires dès qu'on enregistre une modification sur un fichier. Un mélange de make, gcc et ccache avec des morceaux de distcc dedans? Mais ça remet beaucoup de choses en question, et quand on en arrive là, il faut peut-être se demander si on ne devrait pas passer à de la compilation just-in-time?

            • [^] # Re: compilateur ?

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

              Le "démon" de compilation qui tourne en arrière plan pour massivement augmenter le performances de build, c'est la solution qu'a choisi l'outil de build Gradle (Java et autres langages JVM) face aux énormes problème de performances de Maven (l'outil de build moderne historique dans le domaine – pas le premier mais avant c'était très manuel, par exemple avec Ant),en parallèle de caches et de build incrémental. Cf leur comparaison pour des détails : https://gradle.org/maven-vs-gradle/

              Ça ne vient pas sans inconvénients : d'une part les problèmes classiques de caches; d'autre part le fait que (même avec Maven) plus grand monde ne comprends exactement ce qui est fait à la compilation du code.

              La connaissance libre : https://zestedesavoir.com

Suivre le flux des commentaires

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