Quelques réflexions techniques sur Dashboard
Nous avons demandé à guiguiguillaume, membre des forums, de bien vouloir nous donner quelques informations et réflexions sur Dashboard. Il nous livre un premier jet, qui sera probablement complété bientôt.
Suite à ton message, j'ai poussé un peu mes recherches sur l'occupation mémoire des widgets. Je te livre les résultats et mes différentes expérimentations, à toi de voir ce qui présente de l'intérêt. J'ai plutôt plus de questions qu'autre chose au sujet des widgets, mais quelques recherches ont fait sortir d'autres choses.
À propos de la lenteur de Dashboard...
Pour éviter les malentendus, je ne parle pas ici de la lenteur du traducteur (sans doute plus lié à systran qu'à la machine hôte), mais bien de la lenteur au lancement / rappel à l'écran de Dashboard.
À la base, je ne suis pas fan du moniteur d'activité, ma machine rame, ou ne rame pas. Les chiffres...
En l'occurence, ma sélection personnelle de 8 widgets rame souvent (sur mon G4 1.25, 512/80@4700tr), c'est pour ça que je suis allé regarder les chiffres, et on peut y trouver des choses intéressantes.
Il faut pas être sorcier pour comprendre assez vite que c'est le swap qui ralentit l'apparition des widgets, et plus encore, le focus souris dessus pour interagir. Un deuxième lancement consécutif de Dashboard est immédiat, tandis que lors du premier, le disque crépite jusqu'à ce que le système rende la main à 100%.
C'est pas vraiment étonnant quand on regarde la quantité de RAM mise en jeu par les widgets. Avec le temps, il n'est pas rare d'en voir certains finir par occuper 15 Mo en réelle... et ça fois 8, on imagine. À ce propos :
- Je n'ai pas bien compris pourquoi la situation se dégrade avec le temps, mais je le constate. La météo utilise 5 Mo à l'ouverture, finit par en prendre 20 ou bout de 3 jours...
- Une portion de cet espace mémoire est sans doute partagée (on ne peut pas simplement sommer les valeurs), et gonfle artificiellement le total, dans une proportion difficile à évaluer.
Je trouvais cela assez exagéré à la base, je me demandais s'il n'y avait pas des erreurs grossières d'architecture. Ma première idée était que chaque Widget devait dupliquer du code de WebKit dans son espace mémoire... mais ça n'aurait pas beaucoup de sens (quel intérêt d'avoir une "librairie" si c'est pour dupliquer son code), et ça ne semble même pas réalisable, comme me l'a fait remarquer jlbechennec dans les forums.
J'ai à peu près éliminé toute idée de relier le temps de swap avec la vitesse / puissance de WebKit, expérimentalement. Si c'était le rendu qui prenait le temps machine, on aurait dû pouvoir retrouver de la performance en étant sûr que les différentes parties du WebKit étaient bien en RAM (non pas en SWAP), et ça, c'est facile de s'en assurer, il suffit de faire tourner Safari sur quelques pages (j'ai fait attention d'avoir des pages avec pas mal de JS, des png, des gif... bref, pour être sûr) avant d'appeler Dashboard. Ça n'a pas d'incidence sensible sur les performances d'appel de Dashboard.
Pour aller plus loin, j'ai décidé de surveiller de près les appels à la mémoire virtuelle, plus particulièrement les pageins d'OSX, pour voir quand est-ce qu'il allait chercher des parties de la mémoire placées en virtuelle pour les mettre en RAM physique. Au moins, j'obtiens une mesure presque fiable de la quantité de mémoire qui transite.
Comme prévu, un appel direct à Dashboard, s'il vient d'être lancé, ne provoque pas de pagein.
Par contre, en saturant bien ma RAM physique (pas difficile, lancer successivement : garageband, 10 pistes; mail, adium, safari, iPhoto, GoLive, Word...) et refaire un appel Dashboard, c'est 6000 à 8000 page-ins que j'ai pu mesurer, avec mes 8 widgets. Testé sans aucun widget lancé, l'appel à Dashboard seul peut faire 100 à 200 page-ins ; l'appel à un Dashboard avec juste une horloge provoque de l'ordre de 500 pageins.
Pour comparaison, sur un système saturé de la même façon, mettre au premier plan iPhoto (mode édition sur une photo) provoque environ 2800-3000 page-ins, chez moi.
Les mesures sont assez imprécises, mais on peut se rendre compte qu'un Dashboard chargé demande 2 fois autant ( ) d'accès mémoire que l'affichage d'un iPhoto en mode édition. Ce qui explique sa lenteur.
À notre tour, on peut expliquer la lourdeur de dashboard quand on regarde l'architecture telle que l'a décrite Apple : pour des raisons de stabilité, les widgets sont des process indépendants (on peut planter un widget, sans planter le serveur de widgets), chacun lié au webkit pour son affichage et l'interprétation du JS, mais aussi chacun lié plus profondément au système (possibilité de faire des appels système, Obj-C notamment, via JS). Ce qui est d'autant plus lourd que ce code ne peut pas être complètement compilé dans le Widget, ce qui laisse du travail à faire au "runtime" ("finir la compilation" lors de l'exécution).
Pour rendre dashboard stable (protection mémoire des widgets) et permettre la programmation facile (mais potentiellement aussi puissante qu'une programmation Obj-C native), on a donc une architecture qui donne une lourdeur conséquente à chaque widget, tournant dans un processus indépendant.
On comprend comme ça pourquoi lancer dashboard est long. C'est l'exemple typique de "10 petits choses finissent par en faire une grosse". D'autant plus que ces "petites choses" sont appelées exactement en même temps, et qu'il y a donc beaucoup de concurrence dans les appels au système.
Est-ce qu'Apple peut gagner en performance là-dessus ? On peut imaginer qu'ils ont déjà pensé à mettre le dessin du dashboard en cache pour pouvoir faire un rendu rapide du bureau "superposé", et du point de vue architectural (ce que j'ai pu en voir), les choix semblent assez judicieux; même si on peut purement théoriquement imaginer d'autres modes d'exécution (moins protégés), qui compileraient (au lancement ou à l'installation) le code des widgets actifs dans un seul contexte d'exécution... enfin... de nombreuses fantaisies sont possibles à ce niveau.
Le problème réside à mon sens dans la restitution en RAM des n contextes d'exécution des n processus pour leur mise à jour au lancement de Dashboard.
Et là pas de miracle, si ces n processus sont en swap, avec tant de concurrence, sur un système saturé (ramener une page en physique, c'est en mettre une autre en swap), c'est long. Bon, rarement plus de 10 secondes pour retrouver le contrôle à 100%, mais c'est une éternité...
Face à cela, plus de RAM pour éviter la mise en swap de dashboard reste encore ce qu'il y a de plus sûr . On peut aussi appeler Dashboard 3 fois par minutes pour être sûr qu'il n'est pas mis en swap, mais ça devient gênant.