L'évolution de Fastboot

Posté par  . Modéré par patrick_g.
Étiquettes :
60
5
jan.
2009
Noyau
L'idée d'Arjan Van de Ven, un développeur du noyau Linux, de tout faire pour réduire le temps de démarrage d'un système GNU/Linux à 5 secondes, a fait son petit bout de chemin depuis ces derniers mois.

Ayant réfléchi à tout ce qui pouvait être responsable de la lenteur de démarrage du noyau, Arjan en a déduit quelques observations, puis une solution. En juillet celui-ci a révélé un petit projet nommé Fastboot.

Pour expliquer ce qu'est fastboot : ce pourquoi il est né et ce qu'il propose, il faut d'abord faire un petit état des lieux de ce qui se déroule en interne au démarrage du noyau. L'initialisation du noyau

Commençons par le commencement.
Le noyau Linux est compilé au format ELF, qui est un format standard d'exécutables largement utilisé dans le monde des Unix. Dans un exécutable ELF, le compilateur (GCC) ainsi que l'éditeur de liens (linker Ld) utilisent beaucoup les sections pour stocker des informations utiles, telles que les fonctions appelées dans les bibliothèques externes, les informations de débuggage, etc.

Un programme destiné à être compilé au format Elf peut même créer ses propres sections pour y stocker du code ou des données spécifiques et destinées à être regroupées. Par exemple, il est tout à fait possible de regrouper le code d'un ensemble de fonctions dans une section spécifique, puis d'extraire l'adresse de cette section pour parcourir toutes les fonctions qui y sont contenues.

Ce genre d'astuce est très utilisée dans le noyau Linux, et notamment pour résoudre un problème d'envergure : la plupart des composants du noyau ont besoin d'exécuter une fonction pour s'initialiser au démarrage. Par exemple les pilotes ont besoin de signaler au noyau qu'ils attachent telles fonctions à tel périphérique matériel, ils ont besoin de signaler qu'ils écoutent sur les fichiers de périphériques (répertoire /dev), ou même d'initialiser un périphérique, voire d'allouer de la mémoire pour la suite.

En bref, chaque composant du noyau, ou presque, a besoin d'exécuter une fonction d'initialisation au démarrage du système. S'il fallait regrouper un appel à toutes ces fonctions dans un fichier source et les appeler les unes après les autres, ce serait un enfer à maintenir et franchement peu élégant.

Ainsi le noyau Linux crée une section nommée .init.text pour ranger toutes les fonctions d'initialisation dedans. Lorsqu'un pilote décide de soumettre une fonction qui s'exécutera au démarrage, il a juste à faire précéder le nom de sa fonction par l'annotation __init, ce qui rangera le code de la fonction dans la section .init.text. Ensuite, il faudra que ce pilote appelle la macro device_initcall pour ranger l'adresse de sa fonction dans une autre section appelée .initcallxx.init

Cela ne sert pas à grand chose d'expliquer ce que signifie le xx ici, mais il est remplacé dynamiquement pour définir plusieurs niveaux d'initialisation, par exemple le cœur du noyau peut avoir besoin de s'initialiser avant le système de fichiers, etc.

Exemple :
int __init ma_fonction(void);
device_initcall(ma_fonction);

À la compilation, GCC va regrouper toutes ces fonctions dans la section .init.text et leurs adresses dans la section .initcallxx.init
Le noyau, quant à lui, aura pris soin de baliser la section .initcallxx.init avec deux pointeurs :
  • __initcall_start, le début de la section .initcallxx.init ;
  • __initcall_end, la fin de cette section.

Au démarrage, lorsque le noyau veut exécuter toutes ces fonctions, il procède en utilisant une boucle :
for (call = __initcall_start; call < __initcall_end; call++)
call();

C'est un schéma grossier de ce qui se passe réellement, mais en réalité les choses ne sont pas beaucoup plus compliquées : tous les pointeurs de fonctions contenus dans la section .initcallxx.init vont s'exécuter.

À la fin de cette séquence, la mémoire utilisée pour stocker le code de ces fonctions sera libérée (la section .init.text).

Le problème qui se pose

Comme vous avez pu le voir, ces fonctions sont exécutées les unes après les autres. Ce sont les résultats de ces fonctions qui sont affichés sur votre écran au démarrage. Il peut y en avoir plusieurs centaines qui s'exécutent, certaines sont plus longues que d'autres.

Ce qui peut chagriner ici, c'est que les appels de ces fonctions sont sérialisés, ou encore synchrones. Si le mot peut faire peur, en réalité il traduit un concept simple : la prochaine fonction ne s'exécutera pas tant que la fonction en cours d'exécution n'est pas terminée.

Cela peut faire tiquer si l'on recense les ressources disponibles à ce stade du démarrage :
  • Les machines récentes ont plusieurs processeurs, alors qu'ici, un seul processeur est utilisé à la fois puisque ces fonctions ne vont pas s'exécuter de manière simultanée. Et d'ailleurs les fonctionnalités SMP (multiprocesseur) sont activées à ce stade du démarrage. Mais il semble qu'on n'en profite pas vraiment ;
  • Les fonctions d'initialisation risquent de faire des entrées-sorties, des allocations mémoires, en gros il y a des moments où ces fonctions vont "dormir", en attente de réponse de la part d'un périphérique, ou d'autres ressources du système. C'est dommage, on pourrait profiter de ce temps libre pour exécuter d'autres fonctions d'initialisation ;
  • À ce stade du démarrage, l'ordonnanceur de tâches est déjà initialisé. On peut donc créer des threads et profiter du fait que nous avons plusieurs processeurs pour créer des tâches qui s'exécuteront tout à fait en parallèle. Et quand bien même nous n'avons qu'un seul processeur, on peut profiter de la préemption : lorsqu'une fonction d'initialisation bloque (dort) en attente de ressources, une autre peut profiter du processeur pendant ce temps là.

Juillet 2008, premier jet, premier Fastboot

En juillet dernier, Arjan Van de Ven a posté une première solution découpée en trois patchs :

Cette solution créait un nouveau niveau d'initialisation appelé asynchronous initcall, ce qui signifie fonction d'initialisation asynchrone. Il était donc possible, par le biais de ces patchs, de définir des fonctions d'initialisation qui pouvaient s'exécuter en parallèle à d'autres fonctions d'initialisation. Ou pour faire simple : plusieurs fonctions d'initialisation pouvaient maintenant s'exécuter en même temps, permettant ainsi de profiter des ressources rendues disponibles par la préemption et le multi-processeur.

Par défaut, les fonctions __init continuaient de s'exécuter de manière synchrone, les unes après les autres. Mais les développeurs aventureux et désireux d'optimiser le démarrage du noyau pouvaient tester leur fonction d'initialisation de manière asynchrone.

Ce travail était implémenté en utilisant le système des workqueues. C'est-à-dire un thread s'exécutant dans le noyau dans lequel réside une file d'attente de tâches à exécuter. Les workqueues sont une solution légère : elles ne nécessitent pas de création de multiples threads, on a juste un seul thread qui possède une liste de fonctions à exécuter.

Un nouveau thread de type workqueue était donc créé, et lorsqu'une fonction d'initialisation asynchrone était trouvée, elle était ajoutée en queue de liste du workqueue.

Ce qui implique une chose : ce workqueue n'exécutant qu'une seule tâche à la fois, seules deux fonctions d'initialisation pouvaient s'exécuter en parallèle: la partie synchrone, donc les fonctions __init habituelles, et une fonction exécutée par le workqueue.

Qu'est-il arrivé à cette solution? Il semble que Linus n'ait pas trop apprécié l'approche. L'idée de l'exécution asynchrone ne semblait pas mauvaise, mais il préférait quelque chose de plus granulé. Somme toute, ramener la partie asynchrone du démarrage à des choses plus fines plutôt que sur tout une fonction d'initialisation.

Arjan est donc revenu en ce 4 janvier 2009 avec une nouvelle approche.

Janvier 2009, un fastboot 2, plus granulé

Le 4 janvier 2009, Arjan revient avec une nouvelle approche. L'idée des initcalls complètement asynchrones a été abandonnée au profit d'une API permettant à quiconque de décider quelles parties de ses fonctions d'initialisation seront asynchrones.

Il ne s'agit plus maintenant de rendre toute une fonction d'initialisation asynchrone, mais de décider quelle(s) partie(s) d'une fonction d'initialisation devra s'exécuter de manière asynchrone.

Il suffit d'appeler la fonction
void async_schedule(async_func_ptr *ptr, void *data)
ptr étant la fonction à exécuter et data, les données à lui passer en paramètre.

C'est une idée beaucoup plus souple, laissant plus de contrôle au développeur et permettant ainsi d'éviter des conditions de concurrence, d'incohérences d'états au niveau du système. Exemple : que se passerait-il si le pilote de votre disque n'avait pas fini de s'initialiser pendant le montage de votre système de fichier ?

Pour éviter ce genre de situation, cette nouvelle API fournit de nouveaux outils de synchronisation. Lorsqu'une fonction asynchrone est créée, celle-ci reçoit un "cookie", permettant ainsi de l'identifier par rapport aux autres. Si cette fonction décide à un moment ou à un autre d'attendre que toutes les fonctions asynchrones qui ont été lancées avant elle se terminent, il lui suffit de lancer la fonction
void async_synchronize_cookie(async_cookie_t cookie) en passant son propre cookie. C'est donc un outil de synchronisation entre fonctions asynchrones.
Par exemple si A et B sont des fonctions asynchrones qui font l'état des lieux de certains périphériques. Et si C a été lancée après A et B, et qu'à un moment C a besoin de la liste de tous les périphériques recensés par A et B, alors il lui suffit d'appeler async_synchronize_cookie pour être sûre que A et B ont bien fini leur travail et ont tout trouvé.

Un autre outil de synchronisation a été prévu pour que les fonctions d'initialisation synchrones puissent attendre que toutes les fonctions asynchrones soient terminées.
Pour reprendre l'exemple de tout à l'heure, lorsque la fonction d'initialisation qui va monter la partition racine (/) va s'exécuter, elle voudra être sûre que l'initialisation des périphériques de stockage est terminée, sans quoi elle n'aurait pas de système de fichier à lire. Si ces périphériques sont encore en cours d'initialisation à cause de fonctions asynchrones, alors il suffira d'appeler void async_synchronize_full(void)pour attendre leur terminaison.

Si async_synchronize_cookie permet une synchronisation entre fonctions asynchrones, async_synchronize_full permet de synchroniser entre fonctions synchrones et asynchrones.

Voilà, mal de crâne mis à part, il semble que l'idée soit en bonne voie. Si des commentaires critiques sont évoqués dans la révision de ces patchs, pour l'instant ils semblent seulement concerner de petits détails et non pas l'idée principale, ce qui est plutôt bon signe et augure une bonne voie quant à l'inclusion de ces patchs dans la branche principale du noyau, avec beaucoup de chance pour la fenêtre d'inclusion (merge-window) en cours du 2.6.29, avec un peu moins de chance pour 2.6.30.

Dans tous les cas, il y a de fortes chances qu'on retrouve les évolutions du développement de fastboot dans la branche -tip maintenue par Ingo Molnar.

Voici de quoi dépend la rapidité de démarrage de vos futures distributions Linux.

Aller plus loin

  • # Importance

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

    Voici de quoi dépend la rapidité de démarrage de vos futures distributions Linux.

    Ces optimisations servent à gagner quelques secondes dans le cas ou tu n'as pas d'initrd (ou initramfs...), elles ne se voient pas sinon.

    Elles lui ont sans doute permis de passer de 7 ou 8s à 5s, mais la plupart des distros sont à au moins 20 ou 25s, et beaucoup sont plutot à 40s.

    Il y a beaucoup de choses qui influencent plus sur une distribution générique, les divers services en particulier, ou le temps passé dans l'initrd.

    Il y a donc je pense beaucoup de choses plus visibles pour améliorer le temps de boot.

    Je peux citer par exemple l'ajout du cache à modprobe qui fait passer le coldboot udev de 11s à 7s sur mon laptop (mais arjan n'a pas ce problème il a fait une "distrib" specifique à sa machine).
    • [^] # Re: Importance

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

      C'est clair, j'ai tiqué exactement sur la même phrase. Surtout quand on voit aussi le temps de boot complet, jusqu'à l'affichage du bureau... Il y a du boulot sur pas mal de couches, le noyau n'est qu'une d'entre elles.
      • [^] # Re: Importance

        Posté par  . Évalué à 6.

        Disons qu'on peut maintenant dire que... "presque"-ayé, le boulot sur Linux est fait. Maintenant il s'agit de bien mettre au carré le fastboot et de s'attaquer aux couches supérieures... yaka!
        • [^] # Re: Importance

          Posté par  . Évalué à 1.

          Et Upstart, l'idée d'ubuntu, il y a des benchmarks qui montrent les gains par raport au vénérable sysVinit ? Est-ce que ça permet d'avoir plusieurs tâches qui tournent en parallèle ?

          http://en.wikipedia.org/wiki/Upstart
          http://en.wikipedia.org/wiki/Upstart
          • [^] # Re: Importance

            Posté par  . Évalué à 1.

            Sauf que ça c'est pour démarrer les services alors que, dans la dépêche, il était question du noyau. Sinon, c'est une excellent idée très proche de la gestion SMF dans les Sun Solaris 10.
          • [^] # Re: Importance

            Posté par  . Évalué à 1.

            Il y a aussi le OpenRC de gentoo.
          • [^] # Re: Importance

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

            Pas de benchmark sous la mains, mais une fois activé la parallelisation des script de demarrage (il fallait passer une conf de "none" à "shell") sur mon aspire one, mon boot est devenu presque 2 fois plus rapide :)
    • [^] # Re: Importance

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

      Hop, un p'tit lien sur une série d'articles intéressante sur la correction de certains ralentissements dans le login de GNOME:

      http://mces.blogspot.com/2008/10/improving-login-time-part-1(...)
      http://mces.blogspot.com/2008/11/improving-login-time-part-2(...)
      http://mces.blogspot.com/2008/12/improving-login-time-part-3(...)

      La rapidité de démarrage des distributions se joue sur tous les fronts...
      • [^] # Re: Importance

        Posté par  . Évalué à 1.

        Ouais, enfin ce qu'on a gagné d'un côté, on l'a perdu de l'autre avec le démarrage de la machine virtuelle C# pour tomboy et beagle.

        Je vais pas cracher dans la soupe, ceci dit, tomboy est diablement pratique ! Cette saloperie me manque beaucoup au travail ...
        • [^] # Re: Importance

          Posté par  . Évalué à 0.

          Je l'utilise au TAF sous mon Ubuntu et mes collègues utilisent la version Windows qui n'est pas dite stable mais qui fonctionne bien.
        • [^] # Re: Importance

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

          Moi j'utilise Sticky Notes et je peux donc me passer de C#.

          http://library.gnome.org/users/stickynotes_applet/2.25/stick(...)

          C'est quoi les fonctions fabuleudement géniales qui rendent Tomboy incontournable pour toi ?
          • [^] # Re: Importance

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

            entre autres : l'utilisation façon wiki pour relier plusieurs notes, la recherche intégrée.
            Avant j'utilisais sticky notes et je me retrouvais avec des post-its faisant toute la hauteur de l'écran. En passant à tomboy, j'ai pu tout séparer dans plusieurs notes, tout réduire et commencer une gestion à la GTD, avec une note pour chaque bucket. Après, moi aussi je préférerais avoir un tomboy sans mono...
        • [^] # Re: Importance

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

          Un machine virtuelle ne se démarrer pas. une machine virtuelle c'est un concept "virtuel", qui n'a pas d'existence réelle par nature.
          Le temps de chargement du runtime Mono est ridicule, tu t'en apercevra jamais.
          Après une appli Mono peut être plus lente (à démarrer mais pas seulement) qu'une appli C++ évidemment, mais c'est pas lié au temps de démarrage du runtime Mono.
          • [^] # Re: Importance

            Posté par  . Évalué à 3.

            >>une machine virtuelle c'est un concept "virtuel", qui n'a pas d'existence réelle par nature.<<

            Tu devrais éviter l'abus de 'virtuel': l'implémentation elle est bien réelle..

            Puisque tu affirme que le ralentissement est négligeable, c'est que j'imagine que tu as des chiffre qui mesurent ce ralentissement?
            Pourrais-tu nous les donner?
            • [^] # Re: Importance

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

              $ time ./mono.exe test.exe
              Hello, world !

              real 0m0.140s
              user 0m0.015s
              sys 0m0.000s

              C'est évidemment le temps d'exécution total, t'en déduis ce que tu veux sur le temps de "chargement".
              • [^] # Re: Importance

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

                Ah si si, une machine virtuelle se démarre ! C'est un process comme les autres.

                Je ne connais pas bien mono, mais par exemple pour java, le premier démarrage a froid de la machine virtuelle est non-négligeable (lecture DD, mis en place dans la ram). Sun veut d'ailleurs l'améliorer.

                Après peut-être que Mono est mieux foutu de se côté là, mais franchement je pense que ton exemple à été pris "à chaud", avec un mono déjà démarré.

                Après, j'ai la flemme d'installer mono juste pour un test hello word.
                • [^] # Re: Importance

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

                  Ah si si, une machine virtuelle se démarre ! C'est un process comme les autres.
                  C'est pas la machine virtuelle qui démarre, c'est l'environnement d'exécution qui démarre.

                  Après peut-être que Mono est mieux foutu de se côté là, mais franchement je pense que ton exemple à été pris "à chaud", avec un mono déjà démarré.
                  je pensais que ca se voyait, je démarrer mono dans ce test, il n'était pas démarré avant donc.
                  Mono n'est pas un process qui tourne en tache de fond et qui attend d'exécuter des programmes. C'est pas une VM, c'est un environnement d'exécution qui est démarré à la demande pour exécuter tel ou tel programme, de la même manière que t'appelle perl ou python pour exécuter ton script.
                  Bref, comme tu peux le constater, le temps de démarrage de l'environnement d'exécution pour un pauvre hello world, c'est peanuts.

                  Pour Java, y'a des raisons historiques qui font que la première exécution d'une application est plus "lente", mais c'est pas pour autant qu'il y a un process qui tourne en tâche de fond sur ta machine en attente d'une application Java !
                  • [^] # Re: Importance

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

                    Je n'ai jamais dis qu'il y avait la machine virtuelle qui tourne en tache de fond.

                    Par exemple avec un programme java (plus lent car pas un hello word hein...) :

                    > time java -jar wiihamster.jar

                    real 0m5.235s
                    user 0m0.524s
                    sys 0m0.084s

                    > time java -jar wiihamster.jar

                    real 0m2.042s
                    user 0m0.536s
                    sys 0m0.052s

                    Grande différence. La première fois je n'avais encore jamais lancé java sur cette machine. La deuxième fois si.
                    Et pourtant, pas de process 'java' en tache de fond.

                    N'as tu jamais démarré mono (pour une raison X ou Y) sur ta machine avant de faire ce test (et sans utiliser preload hein...) ? Si non, ce sont les résultats de mono a froid, et je m'excuse donc de ma suspicion : Mono est léger au démarrage.

                    Après, un "environnement d'exécution", pour moi ça veut tout et rien dire. Le vrai process qui se lancera sera "mono" (soit au final la machine virtuelle) qui se démerdera pour lire tous les fichiers et foutre tout ton "environnement d'éxécution" en RAM.
                    • [^] # Re: Importance

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

                      Grande différence. La première fois je n'avais encore jamais lancé java sur cette machine. La deuxième fois si.
                      Oué mais la différence, c'est pas le temps de démarrage de la jvm, c'est juste que lors de la première exécution, la jvm a trouvé des optimisations judicieuses qui ont été "enregistrées" et utilisées lors du 2ème démarrage.
                      Ca vient du mode de fonctionnement de java qui fonctionne initialement comme un interpreteur puis compile les méthodes qui sont souvent utilisées.

                      Mono marche pas pareil. le bytecode exécuté est conçu dès le départ pour être compilé et exécuté en code natif (contrairement au bytecode java initialement prévu pour être interprété). Cela dit on retrouve un problème similaire : au début de l'exécution du programme, il faut compiler le code avant de l'exécuter, et ca prend plus de temps qu'après. Mais ca n'a rien à voir avec le temps de chargement du runtime en mémoire en soit. Ce problème peut être contourner en "précompilant" l'application en code natif sur la machine cible, l'application démarrera alors plus vite (même au démarrage de ta machine). Imagine si j'avais utilisé cette possibilité pour mon hello world ;)

                      N'as tu jamais démarré mono (pour une raison X ou Y) sur ta machine avant de faire ce test (et sans utiliser preload hein...) ?
                      C'est pas la question. Que j'ai exécuté mono avant n'y change rien. Idem pour java : avoir exécuté java avant ne change rien.
                      Ce qui change en java, c'est quand t'as déjà exécuté le même programme avant. Bref, rien à voir avec le temps de démarrage de la jvm en soit. C'est uniquement lié au contexte de ton programme.

                      Après, un "environnement d'exécution", pour moi ça veut tout et rien dire.
                      Ben c'est pourtant ca le terme exacte. C'est un runtime, mono, qui s'exécute dans un process, et qui s'arrange pour exécuter ton bytecode, tout comme ton process python exécute ton script, etc.

                      qui se démerdera pour lire tous les fichiers et foutre tout ton "environnement d'éxécution" en RAM.
                      Oué bah oué, tu sais, même C++ a un "runtime", php aussi, python aussi, à part le C...
                      Dès que le langage de programmation se base sur la présence de services (garbage collector, type check, introspection, etc.), il faut un runtime capable de charger ces services additionnels.

                      Le vrai process qui se lancera sera "mono"
                      Tu peux compiler ton programme pour qu'il inclu le runtime, et tu le verras pas, et ton programme n'aura à aucun moment le nom "mono".
                      • [^] # Re: Importance

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

                        Tes arguments semblent convaincants, cependant je me souviens clairement avoir déjà lu que le premier démarrage de la JVM (a froid donc) est lent à cause du fait de devoir tout mettre en RAM (notamment en lisant un fichier de plus de 40Mo...). Le second lancement de la JVM n'ayant pas ce problème. Et que Sun bossait sur l'amélioration de ce lancement a froid de la JVM pour enlever quelques secondes.

                        Malheureusement je ne retrouve plus le lien.

                        Tout ça pour dire que, __dans le cas de Java__, le démarrage de la JVM en elle-même est conséquent (a cause de la grosse taille de la librairie standard). J'ai juste fais le même parallèle avec Mono (car il possède également une grosse librairie), sans vraiment pouvoir le prouver, n'ayant pas testé.

                        Après, je veux bien croire que le second lancement de l'appli est plus rapide (optimisations déjà faites), mais n'empêche que c'est également le cas pour la JVM elle-même, et je pense que c'est surtout ça qui a fait diminuer de moitié le lancement de mon prog.

                        Entre nous, si .net/mono arrive a faire en sorte que le lancement de la machine virtuelle et le chargement des libs ne se sentent pas sur le démarrage de l'appli, chapeau bas, je n'arrive pas à imaginer comment ils ont fait. J'espère cependant que c'est le cas, car je trouve personnellement Java un poil trop lourd (surtout Swing en fait).
                        • [^] # Re: Importance

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

                          les libs toussa, c'est une problématique qui n'est pas propre à mono ou java, n'importe quel soft qui utilise des libs externes doit les lire et les charger en mémoire.
                          Ce qu'il faut retenir, c'est que mon exemple t'as clairement montré que le temps de chargement du runtime est négligeable (j'ai refait le test après avoir redémarrer ma machine), et c'est bien le principal.
                          • [^] # Re: Importance

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

                            > Ce qu'il faut retenir, c'est que mon exemple t'as clairement montré que le temps de chargement du runtime est négligeable (j'ai refait le test après avoir redémarrer ma machine), et c'est bien le principal.

                            Ok, voila la réponse que j'attendais, il semblerait donc en effet que Mono soit plus efficace que Java sur ce point là, à savoir le temps de démarrage.
                            • [^] # Re: Importance

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

                              Après si tu veux vraiment comparer, faudrait tester avec un helloworld en java pour voir le temps effectif de démarrage de la jvm sans tenir compte du temps d'exécution du programme.
                              • [^] # Re: Importance

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

                                De mémoire le démarrage à froid de la JVM, même pour un helloworld, est plus long que les résultats que tu obtiens avec Mono. Après effectivement j'ai pas refais le test depuis un bon moment (ptet même sur du Java5) et on à peut-être pas la même machine.

                                A retester dès que j'ai un peu de temps, mais j'ai pas l'impression que ça se soit beaucoup amélioré.
                    • [^] # Re: Importance

                      Posté par  . Évalué à 1.

                      attention, il y a le cache linux qui joue un role aussi (les pages chargées ne sont pas rechargée mais deflagé de invalides à valide).

                      Mais néanmoins, que ce soit pour mono ou pour java, il y a bien une machine virtuelle qui tourne derriere, donc un processus dédié, donc si celui ci est déjà charger, le prochain démarage du programme java/.net sera plus rapide.
    • [^] # Re: Importance

      Posté par  . Évalué à 5.

      > Je peux citer par exemple l'ajout du cache à modprobe qui fait passer le coldboot udev de 11s à 7s sur mon laptop

      C'est à dire?
      Ca m'intéresse, as-tu un article, une URL sur le sujet?
    • [^] # Re: Importance

      Posté par  . Évalué à 7.

      Oui, effectivement cette phrase a l'air d'être teintée d'absolu, j'aurais du nuancer un peu plus le propos.

      Même au niveau noyau, il y a bien d'autres enjeux pour raccourcir le temps de démarrage. D'ailleurs la discussion sur la dernière mouture de fastboot a soulevé de nouvelles questions sur le délai d'attente concernant les tests d'interruptions, la manière de dresser la liste des périphériques etc...
      • [^] # Re: Importance

        Posté par  . Évalué à 7.

        Merci pour ton article, il est fort intéressant surtout quand on travaille dans l'embarqué.

        En effet le temps de boot du kernel est très restrictif dans l'utilisation de Linux sur des systèmes embarqués, comme les téléphones. 7s de démarrage au minimum c'est intolérable. Sur un processeur ARM le temps de boot du kernel est proche de 3s au mieux, avec le minimum de drivers, et cachant le chargement des modules lors de l'initialisation des services, enfin en utilisant tous les trucs possibles et imaginables pour améliorer ce temps.

        Par contre il y a toujours des drivers au sein du kernel qui peuvent démarrer ensembles, écrans (le 's' a son importance), audio...

        Merci pour l'article. Il est très bien.
    • [^] # Re: Importance

      Posté par  . Évalué à 3.

      Elles lui ont sans doute permis de passer de 7 ou 8s à 5s, mais la plupart des distros sont à au moins 20 ou 25s, et beaucoup sont plutot à 40s.

      La vache! Comment faites-vous? Sur mon fixe je suis à plus de 200s ...
      • [^] # Re: Importance

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

        On a Linux, pas MS Windows ;)
        • [^] # Re: Importance

          Posté par  . Évalué à 2.

          J'ai un ordinateur sous MS Windows qui se lance en moins de 30 secondes (cette créature mythique existe !). Bon, XP hein, pas Vista, qui se lance en moins de 30 secondes chez mon frère, qui a 8 Go de RAM (vous avez bien lu).

          Haha, on est pas vendredi, mais troller ça réchauffe pendant la nuit :(
          • [^] # Re: Importance

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

            8Go sur un PC Windows, alors qu'il ne sait pas gérer plus de 4Go. Les 30 secondes chez ton frère, c'est pour sortir de la mise en veille mémoire pas pour démarrer le système.
            • [^] # Re: Importance

              Posté par  . Évalué à 7.

              Le temps de boot est reelleement important sur un desktop ou l'utilisateur est impatient.
              On peut se poser la question de la pertinence de la vitesse du boot quand la vraie solution serait d'avoir un suspend to ram/disk efficace et de rebooter une fois par mois pour les updates de secu.

              Un suspend to ram, ca reduit *drastiquement* le temps de chargement (a vue de nez sur macos, 1s, peut etre 2, windows est pas mal a la traine derriere, linux on est content quand le kernel se vautre pas a la sortie de la veille), pas besoin de demarrer le window/desktop manager, on retrouve ses fenetres commes elles l'etaient etc.
              Et le suspend to disk dans le cas de laptop qui va rester comme ca longtemps, histoire de pas atomiser la pauvre batterie.

              Bref, resoudre le probleme du boot trop long reviendrait peut etre a avoir un suspend qui fonctionne bien et qui ne casse pas toutes les 2 versions de kernel.
            • [^] # Re: Importance

              Posté par  . Évalué à 3.

              Heu non, Vista détecte et utilise bien les 8 Go, c'est une version 64 bits.
              • [^] # Re: Importance

                Posté par  . Évalué à 1.

                Bon, XP hein, pas Vista, qui se lance en moins de 30 secondes chez mon frère, qui a 8 Go de RAM (vous avez bien lu).

                Heu non, Vista détecte et utilise bien les 8 Go, c'est une version 64 bits.


                Faudrait savoir: XP démarre en 30 secondes mais Vista détecte bien les 8Go de RAM ne veut pas dire que XP détecte bien les 8Go de RAM.

                « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                • [^] # Re: Importance

                  Posté par  . Évalué à 1.

                  Mille excuses, j'ai effectivement oublié un « lui » dans mon premier message. Il fallait à la place lire « Bon, XP hein, pas Vista, qui lui se lance en moins de 30 secondes chez mon frère, qui a 8 Go de RAM (vous avez bien lu). »
                • [^] # Re: Importance

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

                  Windows XP 64 bits détecte très bien 8 Go de RAM.
                  • [^] # Re: Importance

                    Posté par  . Évalué à -3.

                    Je ne sais pas ce que Windows détecte et je m'en fous. Je voulais juste faire remarquer que ses deux post étaient incohérants.

                    « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                    • [^] # Re: Importance

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

                      Dis donc, c'est très intéressant de mettre en évidence une incohérence sur le fond si t'en a rien à péter du fond.
                      • [^] # Re: Importance

                        Posté par  . Évalué à -1.

                        C'est pas parce que je me fous de savoir si XP détecte bien 8Go que je ne veux pas savoir ce que voulait dire l'auteur et qui n'avait rien à voir avec XP mais avec Vista, c'est cette incohérence qui a mis en évidence qu'il avait oublié un mot qui changeait le sens de sa phrase.

                        « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

  • # Chapeau

    Posté par  . Évalué à 10.

    Beau travail du développeur... bien rendu par cette excellente dépêche !

    Je trouve étonnant que la parallélisation des initialisations ne soit pas apparue plus tôt, ça ne semble pas une idée si farfelue pourtant...

    Et combien de temps avant qu'un nombre significatif de pilotes soit mis à jour avec l'API ? Et quand on utilise du vieux matos avec des pilotes qui n'évoluent plus trop ?
    • [^] # Re: Chapeau

      Posté par  . Évalué à 7.

      Je trouve étonnant que la parallélisation des initialisations ne soit pas apparue plus tôt, ça ne semble pas une idée si farfelue pourtant...

      En réalité il ya déjà eu des tentatives de ce genre par le passé.
      Je cite un message d'Ingo Molnar:

      http://lkml.org/lkml/2008/7/20/24

      Pour traduire un passage:

      "bonne idée - et j'aime bien la manière d'amener ça petit à petit.
      La plupart des tentatives précédentes de faire du démarrage parallèle avaient pour défaut de vouloir trop en faire d'un coup"


      Il faut voir aussi que se pose un lourd problème de synchronisation.
      Lancer des fonctions asynchrones, c'est bien mais il y a toujours des étapes précises à suivre, il faut lister les périphériques avant de leur attribuer un numéro d'inode, il faut lister les disques de stockage avant de se lancer sur le montage de systèmes de fichiers etc....

      D'ou ce soucis de devoir "synchroniser" les appels asynchrones. Et ce n'est pas une tâche aisée car il faut être sûr d'avoir bien deréssé la liste de chacune des dépendances.

      Et combien de temps avant qu'un nombre significatif de pilotes soit mis à jour avec l'API ? Et quand on utilise du vieux matos avec des pilotes qui n'évoluent plus trop ?

      A mon avis ça va prendre du temps. Je pense même que seules certaines parties significatives, celles qui seront reconnues pour consommer beaucoup de temps d'execution, seront éventuellement adaptées en asynchrone, si tant est que fastboot trace bien son chemin.
    • [^] # Re: Chapeau

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

      Beau travail du développeur... bien rendu par cette excellente dépêche !

      +1. Claire et pédagogique, du beau boulot, j'ai même cru que ça venait de patrick_g :-))

      Je trouve étonnant que la parallélisation des initialisations ne soit pas apparue plus tôt, ça ne semble pas une idée si farfelue pourtant...

      Bof, je crois que c'est à cause de tous ces kikoololeurs qui ont gardé l'habitude d'éteindre leurs péssés tous les soirs, forcément le matin faut rebooter.
      Tout ça pour éviter la prière à Saint Uptime, bande de mécréants !!!
      • [^] # Re: Chapeau

        Posté par  . Évalué à 3.

        Tu peut remplacer kikoololeurs par écolo, pigre ou ....................gens normaux. Le PC ne sert pas forcement de serveur pour tous le monde :p
      • [^] # Re: Chapeau

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

        peut-etre que ces gens n'habitent plus chez leurs parents et paie eux-même leur facture d'éléctricité ?
        • [^] # Re: Chapeau

          Posté par  . Évalué à 1.

          Je paie ma facture d'électricité, mais ce n'est pas mon PC (un fixe, mais qui doit consommer 50 W au repos, et encore) qui va l'alourdir. Ça doit faire 0,2 E par jour à tout casser. Je préfère avoir mon PC dispo quand je veux, avec toutes mes applis ouvertes (l'écran lui se met en veille, bien sûr).
  • # Fort intéressant...

    Posté par  . Évalué à 9.

    Tout d'abord bravo et merci pour ces explications claires et compréhensibles, même pour un néophyte du noyau et des drivers, comme moi.
    Un article comme ça, ça fait toujours plaisir à lire :-)
    Du "patrick_g" dans le texte !

    Par contre, quelques détails m'échappent, quand je lis ceci :
    "Par exemple si A et B sont des fonctions asynchrones qui font l'état des lieux de certains périphériques. Et si C a été lancée après A et B, et qu'à un moment C a besoin de la liste de tous les périphériques recensés par A et B, alors il lui suffit d'appeler async_synchronize_cookie pour être sûre que A et B ont bien fini leur travail et ont tout trouvé."
    Comment C indique-t-il qu'il n'attend que A et B, et pas autre chose ? En passant les cookies de A et B à la fonction "async_synchronize_cookie" ? Mais comment les connait-il dans ce cas ?
    Ou alors est-ce simplement le fait d'avoir été lancé après A et B qui sous-entend qu'il attend ces derniers ? Dans ce cas, Z risque de devoir attendre des fonctions inutilement...
    • [^] # Re: Fort intéressant...

      Posté par  . Évalué à 2.

      Voilà c'est tout à fait ça, c'est le fait que C a été créé après A et B.
      En fait, en interne ces cookies ne représentent qu'un compteur interne.

      A aura le cookie 0, B aura le cookie 1 et C aura 2.

      Lorsque c appèle async_synchronize_cookie, il passe en paramètre son propre cookie, c'est à dire 2.

      Puis async_synchronize_cookie va dormir tant que toutes les fonctions asynchrones ayant un cookie plus petit que 2 ne sont pas terminées.

      Cette histoire de cookie-compteur permet de s'assurer du bon ordre au niveau de la synchronisation.
      • [^] # Re: Fort intéressant...

        Posté par  . Évalué à 3.

        Oki, merci pour les précisions...
        Mais du coup, le 2° cas (celui où Z devra attendre inutilement d'autres fonctions lancées avant lui) que je soulève risque de se présenter assez souvent...
        • [^] # Re: Fort intéressant...

          Posté par  . Évalué à 1.

          Oui mais ça ne pose pas de problème.
          Si C se synchronise, donc que C attends A et B, et que Z se synchronise un peu en même temps, donc qu'il attends A, B, et C, ça ne pose aucun soucis.

          Hmm, par exemple tu imagines quoi comme problème qui pourrait arriver?
          • [^] # Re: Fort intéressant...

            Posté par  . Évalué à 4.

            Et si Z veut se synchroniser sur A mais pas sur C et que C prend 10sec à s'executer, il va quand même devoir attendre C ?
            • [^] # Re: Fort intéressant...

              Posté par  . Évalué à 3.

              voilà, c'est là où je voulais en venir :-)
            • [^] # Re: Fort intéressant...

              Posté par  . Évalué à 2.

              Ca, par contre c'est pas prévu pour :-)

              En ce cas, il faut lancer Z avant C...
              • [^] # Re: Fort intéressant...

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

                Qu'est qui définit l'ordre de lancement ? Il y a un ordre de priorité lors de la définition de __init ?
                • [^] # Re: Fort intéressant...

                  Posté par  . Évalué à 6.

                  Tout à fait.
                  Le __init est un raccourci pour dire que le code de la fonction appartient à la section .init.text, permettant ainsi de libérer cette mémoire après l'appel de ces fonctions qui ne seront plus utilisées.

                  Là où se joue l'ordre d'appel c'est à la définition du device_initcall(fonction).

                  Voici un extrait de include/linux/init.h

                  #define __define_initcall(level,fn,id) \
                  static initcall_t __initcall_##fn##id __used \
                  __attribute__((__section__(".initcall" level ".init"))) = fn

                  /*
                  * Early initcalls run before initializing SMP.
                  *
                  * Only for built-in code, not modules.
                  */
                  #define early_initcall(fn) __define_initcall("early",fn,early)

                  /*
                  * A "pure" initcall has no dependencies on anything else, and purely
                  * initializes variables that couldn't be statically initialized.
                  *
                  * This only exists for built-in code, not for modules.
                  */
                  #define pure_initcall(fn) __define_initcall("0",fn,0)

                  #define core_initcall(fn) __define_initcall("1",fn,1)
                  #define core_initcall_sync(fn) __define_initcall("1s",fn,1s)
                  #define postcore_initcall(fn) __define_initcall("2",fn,2)
                  #define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s)
                  #define arch_initcall(fn) __define_initcall("3",fn,3)
                  #define arch_initcall_sync(fn) __define_initcall("3s",fn,3s)
                  #define subsys_initcall(fn) __define_initcall("4",fn,4)
                  #define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s)
                  #define fs_initcall(fn) __define_initcall("5",fn,5)
                  #define fs_initcall_sync(fn) __define_initcall("5s",fn,5s)
                  #define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs)
                  #define device_initcall(fn) __define_initcall("6",fn,6)
                  #define device_initcall_sync(fn) __define_initcall("6s",fn,6s)
                  #define late_initcall(fn) __define_initcall("7",fn,7)
                  #define late_initcall_sync(fn) __define_initcall("7s",fn,7s)


                  Le level définit l'ordre d'appel. Plus il est petit, plus l'appel se fait au début.
                  On commence par les early_initcall (avant que le multiprocesseur soit activé).
                  Ensuite viennent les fonctions du coeur du noyau, puis les éléments relatifs à l'architecture, puis les sous-systèmes, puis le système de fichier, etc....

                  Ce qui donnera une section .initcall0.init pour les pure_initcall, .initcall1.init pour le coeur du noyau etc....

                  Et voilà, les pointeurs de fonctions seront regroupés par sections et rangés dans le bon ordre :-)
  • # Intéressant

    Posté par  . Évalué à 6.

    Très bonne new bien détaillée et bien expliquée!
  • # Et les scripts de démarrage?

    Posté par  . Évalué à 5.

    Le problème ne se pose t il pas aussi pour les scripts de démarrage?
    A ma connaissance, tous les scripts de /init.d démarrent séquentiellement. En les parallélisant on gagnerait un temps non négligeable. Le problème est de mettre en place un mécanisme pour savoir quels sont les scripts qui ont besoin d'autres scripts afin que ceux ci démarre en premier. Bref, la problématique est la même que pour le noyau. Il me semble qu'une distribution avait déjà tenté un truc du genre...
    • [^] # Re: Et les scripts de démarrage?

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

      Pour Debian, j'étais tombé sur un message indiquant une solution pour réduire de plus d'un tiers le temps de démarrage. C'est ici :
      http://lists.debian.org/debian-devel/2008/05/msg01119.html

      Pour ma part, depuis que la mise en veille fonctionne, je n'utilise plus que ça : mon système est opérationnel en 1 à 2 secondes maxi !
    • [^] # Re: Et les scripts de démarrage?

      Posté par  . Évalué à 3.

      le sysvinit a déjà des remplaçants :
      - upstart (ubuntu)
      - initng (debian/ubuntu/fedora/gentoo)
      sont les plus connus et déjà utilisables.

      Après il y a des approches plus prometteuses, mais qui demandent plus de boulot, comme launchd, déjà à l'œuvre dans Mac OS
      • [^] # Re: Et les scripts de démarrage?

        Posté par  . Évalué à 1.

        Au passage Fedora utilise maintenant upstart en mode compatibilité depuis la version 9 (très peut pour la F10 à moitié pour la F9 et plus du tout normalement pour la F11...)...
      • [^] # Re: Et les scripts de démarrage?

        Posté par  . Évalué à 1.

        - initng (debian/ubuntu/fedora/gentoo)

        J'ajoute aussi OpenRC et baselayout-2* sous Gentoo, une voie plus «officielle» que initng. La combinaison permet parfois de diviser par deux le temps de démarrage des services (ce fut le cas pour moi). De plus, en mode parallèle, on gagne encore du temps. Toujours en phase de test mais c'est très prometteur.

        Le truc ici est de simplifier les scripts de démarrage et de les affarnchir de leur dépendance à bash, beaucoup plus lourd que nécessaire. En diminuant fortement aussi le nombre de «sub-shells», on réduit de manière draconienne le temps de démarrage.

        Par exemple, il est possible de passer de 50 à 25 secondes -- juste après avoir sélectionné le système d'exploitation dans Grub et l'affichage du login à la console; sans X donc. En mode parallèle, avec X, Slim et XFCE4, sur ma machine, il me faut environ une minute pour avoir la main sur le bureau. X et XFCE prennent environ 40 secondes, c'est énorme.

        Il y a certainement moyen d'optimiser X/XFCE mais bon, ce n'est pas ce qui m'intéresse pour le moment.
        • [^] # Re: Et les scripts de démarrage?

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

          Oui, et on parle aussi de prcsys sous Mandriva en dessous. Ce qui me fait me poser une question: pourquoi il n'y a pas de solution unifiée sur ce point ? On dirait que chaque distrib a préféré développer sa propre solution.
    • [^] # Re: Et les scripts de démarrage?

      Posté par  . Évalué à 2.

      Les scripts dans init.d sont préfixés par une valeur numériques, non ?
      Donc cette valeur peut toujours servir à gérer les dépendances entre scripts (tant que les scripts 10... n'ont pas fini, impossible de lancer les scripts 20...) ?
    • [^] # Re: Et les scripts de démarrage?

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

      Sur les Debian il y a le paquet insserv qui permet de lancer en parallèle les scripts des démarrage, il utilise les en-tête LSB pour gérer les dépendances entre les scripts.

      http://packages.debian.org/lenny/insserv
    • [^] # Re: Et les scripts de démarrage?

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

      La parallélisation des scripts de /etc/init.d a déjà été réalisée par pinit dans Mandriva depuis 2 ans. L'astuce consiste à déclarer les dépendances des différents services dans des "commentaires" structurés des scripts. Voici un exemple : le démarrage de ntpd, le serveur de temps :

      ### BEGIN INIT INFO
      # Provides: ntpd
      # Required-Start: $network
      # Should-Start: $named
      # Required-Stop: $network
      # Should-Stop: $named
      # Default-Start: 2 3 4 5
      # Short-Description: Synchronizes system time using the Network Time Protocol (NTP)
      # Description: The Network Time Protocol (NTP) is used to synchronize a computer's time
      # with another reference time source.
      ### END INIT INFO


      Cette partie comprend également toutes les informations utiles à drakxservices qui permet à un débutant de gérer les services de sa machine.
      Ainsi, le script est toujours compatible system V.
      On pourra se reporter à http://linuxfr.org//2006/08/29/21258.html
      • [^] # Re: Et les scripts de démarrage?

        Posté par  . Évalué à 4.

        d'ailleurs, avec la Mandriva 2009 Spring (la version alpha), je suis en moins de 20 secondes sous KDM, sans changer les services par défaut, avec le driver nv. Malheureusement, il faut encore 20 secondes pour finir l'initialisation du desktop, après s'être loggé dans KDM.
  • # Il ne reste plus qu'à...

    Posté par  . Évalué à 0.

    ...attendre que patrick_g annonce l'intégration de fastboot dans les prochaines dépêches sur le noyau...

    Sinon, cela semble être la continuité de la chose, le nombre de processeurs/cœurs augmente, il faut donc adapter les programmes pour les utiliser correctement...
    • [^] # Re: Il ne reste plus qu'à...

      Posté par  . Évalué à 3.

      Bof pour la "continuité", cette optimisation n'est pas spécialement réservée aux CPUs multicoeurs/SMPs: d'ailleurs Arjan a bossé sur son laptop Asus901 (avec un seul CPU).
      • [^] # Re: Il ne reste plus qu'à...

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

        Pas multicoeurs mais multithread ;)

        Sinon jolie news et effectivement j'ai cru lire du patrick_g jusqu'à ce que je regarde l'auteur de cette dépêche.

        Du bon boulot vivement la prochaine :)
        • [^] # Re: Il ne reste plus qu'à...

          Posté par  . Évalué à 8.

          Du bon boulot vivement la prochaine :)

          Ben merci pour ces compliments.
          Je pense que j'en referai d'autres alors :-)

          J'ai déjà une petite idée pour la prochaine dépêche :-)
    • [^] # Re: Il ne reste plus qu'à...

      Posté par  . Évalué à 2.

      > Sinon, cela semble être la continuité de la chose, le nombre de processeurs/cœurs
      > augmente, il faut donc adapter les programmes pour les utiliser correctement...

      Si le principal point de contention est la CPU...

      J'ai l'impression (mais sans avoir fait de mesures, hein;) que le goulot d'étranglement, lors du chargement de l'espace utilisateur (et plus particulièrement des gros DE), sont plutôt les I/O, pour le moment.

      Entendez-vous vos disques crépiter, au lancement de gnome ? Voyez-vous votre page cache si dodu, lorsque vous pouvez enfin lancer un "cat /proc/meminfo" au démarrage ?
      Le lancement de ces services nécessite l'ouverture et la lecture d'une myriade de petits fichiers répartis un peu partout sur le système de fichier. Dans l'état, la parallélisation fera gagner en temps CPU, mais la contention des accès disques n'en sera pas améliorée ; elle sera plutôt empirée (en rendant les accès encore plus aléatoires / moins séquentiels).

      Pour rappel, un bon disque SCSI ou SAS est capable d'environ 200 IOPS : c'est peu. C'est encore une ressource précieuse, partagée entre les tout les logiciels qui doivent se lancer, et pour laquelle il nous reste une belle marge d'amélioration. A moins qu'on ne saute cette phase, en misant sur la généralisation du SSD ?
      • [^] # Re: Il ne reste plus qu'à...

        Posté par  . Évalué à 5.

        Oh et pendant que j'y suis (et que je parle de mesure) :

        Connaissez-vous seekwatcher ? C'est un outil basé sur blktrace permettant de mesurer et visualiser finement les accès disques coûteux sur une période de temps (en mettant en vis à vis le débit, les déplacements de têtes par seconde, les offsets sur le disque). Développé par Chris Mason (de btrfs) à Oracle :

        http://oss.oracle.com/~mason/seekwatcher/

        Ca donne des choses comme ça, beaucoup plus lisibles que la sortie brute de blktrace ! :
        http://oss.oracle.com/~mason/seekwatcher/ext3_vs_btrfs_vs_xf(...)
        http://oss.oracle.com/~mason/seekwatcher/ext3-compilebench.m(...)
        • [^] # Re: Il ne reste plus qu'à...

          Posté par  . Évalué à 2.

          Je connaissais blktrace mais pas les outils qui l'exploitaient... Ben dis donc, avec l'évolution
          du tracing dans Linux on arrive à de belles choses. C'est qu'il devient de plus en plus introspectif le noyal... :-)
      • [^] # Re: Il ne reste plus qu'à...

        Posté par  . Évalué à 2.

        Pour savoir ce qui limite le temps de chargement de ton système Linux, il existe l'outil « bootchart » qui permet de visualiser (image PNG ou SVG) l'utilisation par les processus de démarrage du CPU et du disque : du coup, tu peux voir si à des moments donnés, le CPU se tourne les pouces (en attendant le disque, ou pire, endormi par un script), et quels sont les scripts qui sollicitent ton disque...
      • [^] # Re: Il ne reste plus qu'à...

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

        ça fait un bout de temps que je pense à coder un outil capable de determiner quels sont les secteurs disques qui ont été utilisés pendant le boot (dispos dans le cache par ex), et un deuxième outil capable de mettre ces secteurs en cache au démarage, mais dans l'ordre le plus efficace pour le disque dur. Clairement, lire 1 5 2 7 4 9 3 8 c'est moins rapide que lire 1 2 3 4 5 7 8 9 meme s'il y a des trous ou des sauts.

        Manque de temps, manque de skills (j'ai pas encore très bien compris quelles étaient les tables à interroger)
        • [^] # Re: Il ne reste plus qu'à...

          Posté par  . Évalué à 3.

          C'est marrant, dans la plupart disques durs récents SATA, il y a une fonctionnalité appelée NCQ qui permet ce genre de tri pour limiter les déplacements de la tête de lecture.
          Logiquement c'est une option qui est activable via le BIOS.
          Il y a un driver dans Linux qui permet de gérer cette technique, c'est peut-être intéressant d'y jeter un coup d'oeil :)
          Perso j'aimerais bien un logiciel tel que preload qui permet en théorie de charger en mémoire les fichiers les plus souvent utilisés. Le soucis c'est que je n'ai jamais vu aucune différence de rapidité après l'installation de preload ^^
      • [^] # Re: Il ne reste plus qu'à...

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

        Ce qui me frappe aussi c'est le nombre de processus lancés au démarrage. Il suffit de voir le PID du dernier processus. De mémoire, sur mon Linux, je tourne aux alentours de quelques milliers.

        Et sur Mac OS (qui est plus rapide), c'est de l'ordre de 200.

        Je me demande si il ne serait pas possible de réduire drastiquement le temps de démarrage si on arrêtait d'utiliser des scripts shell, mais par exemple des langages de scripts légers, et utiliser des bibliothèques.

        Par exemple au lieu de lancer l'exécutable modprobe (par exemple) juste utiliser une fonction dans une bibliothèque qui ferait la même chose.
  • # bsd ??

    Posté par  . Évalué à 1.

    Excusez moi mais quand est-il chez netBSD & co ?
    Le script d'initialisation, l'asynchronisation au niveau du noyau ?
    Merci
    • [^] # Re: bsd ??

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

      Les scripts d'init sont appelés séquentiellement. Il n'y a pas d'équivalent de fastboot (que je sache).

      Le problème de fastboot me semble quand même la complexité de gérer et de maintenir les dépendances ? Si c'est juste pour gagner une seconde ?

      Il faut aussi que le noyau soit finement locké, pas très utile de lancer 50 fonctions en concurrence pour le même lock.

      Il m'a semblé voir passer une tentative pour lancer les scripts d'init en parallèle sous FreeBSD mais de mémoire ça n'avait pas soulevé l'enthousiasme des foules.

      Ça me semble faisable, les scripts sont ordonnés un peu à la manière de pinit de Mandrake (c'est le 'RCng' pompé chez NetBSD) par un outil rcorder(8)

      Par exemple /etc/rc.d/nfsd
      #!/bin/sh
      # PROVIDE: nfsd
      # REQUIRE: mountd
      # KEYWORD: nojail

      OpenBSD utilise le "vieux" style de script rc.

      les pixels au peuple !

      • [^] # Re: bsd ??

        Posté par  . Évalué à 2.

        >Le problème de fastboot me semble quand même la complexité de gérer
        >et de maintenir les dépendances ? Si c'est juste pour gagner une >seconde ?

        J'avoue ne pas vraiment comprendre cette remarque... Aujourd'hui déjà les scripts ne peuvent pas se lancer dans n'importe quel ordre, donc il existe déjà un système de dépendance. Il est probablement implicite, avec des numéros pour déterminer l'ordre ou quelque chose du genre, ce qui me parait encore plus compliqué à maintenir. Si quelqu'un pouvait m'éclairer sur comment c'est implémenté actuellement d'ailleurs, je prend...
  • # Sujet Intéressant!

    Posté par  . Évalué à 1.

    Cela fait quelques jours (et nuits) que je m'attaque au sujet.
    Sous Debian, je parallèllise avec startpar.
    J'ai atteint 9,5 secondes pour booter
    Réseau USB kde3.3 + 6 consoles textes, LVM, mais pas sur
    partitions système.

    Il est vrai que j'ai dégraissé plusieurs services non primordiaux,
    en privilégiant le chargement à la demande.
    D'après mon analyse
    J'ai détecté 3 problèmes :

    1 init : passage du niveau S au niveau N : temps mort.
    En effet , à ce stade, il relance le script rc qui va boucler
    sur le nouveau runlevel, mais la règle est que tous les
    scripts du runlevel S doivent être terminés.

    2 sourcing : tous les scripts ou presque sourcent des fichiers
    et ce sont souvent les même = (redondances + IO inutiles)

    3 execution du noyau : j'ai 4 à 6 seconde mortes sans activité.
    Plus le noyau est récent et plus c'est long.

    Ma meilleure performance est avec un noyau 2.6.8
    Je travaille toujours avec des noyaux recompilés SANS l'initrd.
    Je n'utilise pas udev, mais je vais peut-être quand-même y revenir
    car le gain de temps n' est pas si convainquant que cela.

    Si quelqu'un pouvait me dire comment raccourcir l'execution du noyau?
    Merci.

Suivre le flux des commentaires

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