• [^] # Re: Unladen Swallow ?

    Posté par (site web personnel) . En réponse à la dépêche Publication de Unladen Swallow 2009Q3. Évalué à 7.

    Alors, quelques explications sur le gain de consommation mémoire extraordinaire. Tout d'abord, notez que les auteurs soulignent que Unladen Swallow consomme encore beaucoup trop de mémoire par rapport à l'interpréteur de référence.

    Normalement, l'interpréteur Python convertit un programme en bytecode python, conserve ce bytecode en mémoire et l'éxecute dans sa VM. La consommation de mémoire de Python correspond grosso-modo à la mémoire utilisée par la VM, plus tous les modules sous forme de bytecode.

    Ce qui se passe avec la couche LLVM que Unladen Swallow a rajouté, c'est que certains morceaux de bytecode qui sont exécutés très souvent deviennent Hot et sont convertis en un autre bytecode, le bytecode de LLVM (qui s'appelle IR pour Intermediate Representation). Unladen Swallow conserve donc en mémoire le bytecode IR des modules optimisés. Ensuite, lorsque LLVM exécute le bytecode IR, il applique d'une part des optimisations, d'autre part il observe la fréquence d'utilisation des morceaux d'IR et peut décider si certains morceaux reviennent très souvent de balancer son compilateur JIT, qui lui va transformer l'IR en assembleur optimisé à donf.

    On peut donc se retrouver facilement avec en mémoire pour chaque module le bytecode Python, le bytecode IR et l'assembleur. Ca va même plus loin puisque pour optimiser l'IR, les variables Python utilisées sont présentées comme constantes à la couche LLVM. Cela permet de faire un travail d'optimisation plus poussé, mais ça contraint à surveiller lesdites variables. Si certaines valeurs changent, l'IR n'est plus valide, il faut donc relancer une phase de compilation de l'IR et se débarasser de l'IR précédent, devenu obsolète. Et bien sur, faire cette surveillance sur les variables python implique de leur rajouter quelques champs afin de surveiller leur variation, donc augmenter la taille de certains objets Python. Il me semble qu'il y a aussi un cache au niveau de l'IR.

    Pour la version Q2, l'objectif était de mettre en place toute cette infrastructure de compilation. C'est assez complexe comme vous pouvez le constater et la problématique de la mémoire a été laissé de côté pour cette phase. Il faut bien commencer par quelque part.

    Au point que dans certaines versions de Unladen Swallow, l'IR obsolète n'était pas déchargé tout de suite de la mémoire.

    Donc comme vous le voyez, c'est facile de consommer un max de mémoire avec cette architecture. Fondamentalement, Unladen Swallow consommera toujours plus de mémoire que le même code Python, ne serait-ce que par l'instrumentation du bytecode Python nécessaire pour déclencher correctement la partie LLVM.

    Par contre, avec la release Q3, ils ont commencé à regarder d'un peu plus près les grosses sources de consommation, d'où ce gain phénoménal. Pas plus tard qu'avant hier, il y a eu des modifications pour faire encore des gains de consommation mémoire, donc on peut imaginer que la version Q4 rentrera dans le domaine du raisonnable.