C'est globalement ce que j'en avais compris des deux articles du membre de l'équipe chargée du compilateur. L'idée étant de pouvoir rajouter un smart pointerGc<T> dont l'intention serait similaire à Rc<T>. Si la gestion automatique est basée sur du comptage de références, je comprends pourquoi la politique de gestion est drastique via le borrow checker (comme éviter des cycles dans le graphe des pointeurs qui sont gérés par des éphémérons dans le cas du GC d'OCaml).
La différence peut être mince, comme tu le soulignes avec les unikernels, mais je dirais qu'un langage système permet de maîtriser suffisamment parfaitement le comportement du code pour pouvoir écrire du code temps-réel (au sens temps réel dur, pas au sens globalement performant).
Mais dans ce cas ne faut-il pas une gestion totalement manuelle de la mémoire pour faire ce genre de chose ? Un langage tel que Rust peut-il s'attaquer à ce genre de problématique avec son mode de gestion automatique ?
Mais justement le lien que j'ai donné explique bien que Haskell va donner de très bon débit, mais va avoir des problèmes de latences ; ton benchmarck au final est équivalent à tester un débit moyen, mais ne va pas du tout tester les problèmes de latences, parce que 1) c'est pénible à tester 2) ce n'est pas ton problème.
Effectivement mon benchmark ne montre que le débit moyen, j'utilise time, mais parce que n'étant pas programmeur je ne connais pas les outils pour faire de la mesure de latence. En réalité, la modification que j'ai apporté au code OCaml de départ est plus un sketch of proof pour régler des problèmes de latence liés au GC. Ce qui fait que je suis passé de 25 s à 5.5 s est que j'ai fait disparaître une action du GC qui est responsable de la latence observée dans l'article que tu as cité sur le GC de Haskell : un parcours de la major heap.
Le tas est composé de deux memory pool : une minor heap et une major heap. La première sert pour les objets à courte durée de vie et est très efficace pour ce qui concerne les temps d'allocation et de désallocation mémoire. Lorsqu'elle est pleine le GC nettoie et transfert les structures encore en vie vers la major heap, puis à chaque fois qu'il fait cela, il nettoie par tranche cette major heap (de manière incrémentale) : c'est ce processus en mode stop the world qui prend plus du temps et génère de la latence. Dans mon code, j'ai adapté la gestion de la mémoire pour ne pas y avoir recours. Cela se passe en trois temps :
(* le memory pool de la minor heap est définie avec une taille * suffisante pour les besoins du calcul : un gros malloc une * bonne fois pour toute *)let()=set_minor_heap(8lslmax_depth)(* c'est la partie proprement calculatoire du code *)letworker(niter,d)=letc=ref0infori=1toniterdo(* je nettoie la minor heap pour éviter des transferts * vers la major heap *)Gc.minor();c:=!c+check(makeid)+check(make(-i)d)done;!c(* le bout de code qui enchaîne les calculs * ne subit plus de latence *)compute~worker~mastertasks;
Sans cela j'avais un grand nombre de major collection, qui sont responsables des latences observées dans le fonctionnement du GC, là où maintenant je n'en ai plus aucune. ;-)
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: On s'en bat le steak
Posté par kantien . En réponse au journal Typage statique pour Python. Évalué à 2. Dernière modification le 05 juin 2016 à 21:43.
C'est globalement ce que j'en avais compris des deux articles du membre de l'équipe chargée du compilateur. L'idée étant de pouvoir rajouter un smart pointer
Gc<T>dont l'intention serait similaire àRc<T>. Si la gestion automatique est basée sur du comptage de références, je comprends pourquoi la politique de gestion est drastique via le borrow checker (comme éviter des cycles dans le graphe des pointeurs qui sont gérés par des éphémérons dans le cas du GC d'OCaml).Mais dans ce cas ne faut-il pas une gestion totalement manuelle de la mémoire pour faire ce genre de chose ? Un langage tel que Rust peut-il s'attaquer à ce genre de problématique avec son mode de gestion automatique ?
Effectivement mon benchmark ne montre que le débit moyen, j'utilise
time, mais parce que n'étant pas programmeur je ne connais pas les outils pour faire de la mesure de latence. En réalité, la modification que j'ai apporté au code OCaml de départ est plus un sketch of proof pour régler des problèmes de latence liés au GC. Ce qui fait que je suis passé de25 sà5.5 sest que j'ai fait disparaître une action du GC qui est responsable de la latence observée dans l'article que tu as cité sur le GC de Haskell : un parcours de la major heap.Le tas est composé de deux memory pool : une minor heap et une major heap. La première sert pour les objets à courte durée de vie et est très efficace pour ce qui concerne les temps d'allocation et de désallocation mémoire. Lorsqu'elle est pleine le GC nettoie et transfert les structures encore en vie vers la major heap, puis à chaque fois qu'il fait cela, il nettoie par tranche cette major heap (de manière incrémentale) : c'est ce processus en mode stop the world qui prend plus du temps et génère de la latence. Dans mon code, j'ai adapté la gestion de la mémoire pour ne pas y avoir recours. Cela se passe en trois temps :
Sans cela j'avais un grand nombre de major collection, qui sont responsables des latences observées dans le fonctionnement du GC, là où maintenant je n'en ai plus aucune. ;-)
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.