Forum Programmation.web Réflexion sur ASM.js ou quand le javascript deviens enfin performant :

Posté par . Licence CC by-sa
4
15
mar.
2013

Sommaire

Tout d'abord, pour info et pour être honnête, ce qu'il faut savoir sur moi, c'est que je ne suis pas le plus grand fan de la prochaine version de javascript, bien que la plupart des améliorations soient une réelle avancée, d'où mon affection pour typescript de microsoft ( je sais, je sais…). Cependant, d'autres fonctionnalités me paraissent un peu compliquées pour les plus-values qu'elles apportent, surtout quand on sait que js est devenu le bytecode du web : pour moi les guards en sont un parfait exemple. Le javascript deviendrait-il le nouveau C++ ?

introduction

Pour le meilleur ou pour le pire, javascript est devenu incontournable. Néanmoins, malgré les efforts constants des navigateurs pour améliorer le moteur, il reste extrêmement lent dans certaines situations, et ce, à cause de certaines limitations intrinsèques au langage (comme le boxing, le garbages collector…). Jusqu’à présent, mozilla refusait un peu la réalité. Lorsque dart est sortie, le seul argument qui me paraissait honnête était le coût de maintenance non négligeable à ajouter à l'existant. Pour native client, l'argument était plus évident : les binaires ou bytecodes n'étaient pas l'idéal pour le web qui est supposé être ouvert tout en introduisant une nouvelle technologie à maintenir. Ainsi, la réponse au problème de la part de mozilla a enfin était annoncé sous le nom d' asm.js: un sous-ensemble de javascript qui permet enfin d'avoir des performances proches de native client (et aussi une protection mémoire similaire du code compilé à la volé dans certain cas…). Cet exploit est réalisé grâce à quelques astuces syntaxiques qui permettent de donner des indices de typages des variables,des restrictions dans les fonctionnalités les plus coûteuses ainsi que l'utilisation d'un buffer (typeArray) comme heap dans le programme pour éviter tout problème de garbage collector…

avis

J'avoue être très agréablement surpris par cette solution : ce n'est que du javascript, ainsi le fallback est évident à mettre en place car il sera exécuté par tout les navigateurs sans aucune modification. Pour toute personne intéressé par le sujet, je vous propose d'aller voir le blog suivant

Cependant, pour un développeur qui aime le bas niveau et le web, tout n'est pas parfait.Tout d'abord, il n'existe que deux types classiques le int et le double. D'après moi, cette restriction provient du moteur même de firefox (spidermonkey/ionmonkey) qui est lui-même limité à ces types. Il existe d'autres raisons  plus obscures qui n'ont de sens que si vous pensez à l'implémentation (les type boolish/intish…). De mon point de vue, ce défaut mineur sera probablement corrigé lorsque les implémentations seront plus matures et que les interactions entre la partie codée en asm.js et javascript seront définies plus strictement. En effet, asm.js permet d’interagir directement avec votre moteur javascript sans passer par des tableaux de bytes, provoquant un besoin de définir les interactions entre le code du js optimisé et le js interne (appelé ffi pour les plus curieux).

Personnellement, j'aurai vu uniquement des ArrayBuffer comme entrée et sortie, ce qui aurait eu l'avantage de simplifier le tout mais surtout de permettre une plus grande souplesse dans les types à l'intérieur du programme optimisé et d'être déjà paré pour les structure binaires d'harmony.

D'après moi, il faut bien se l'avouer et en avoir conscience, si asm.js est implémenté dans les navigateurs, la prochaine étape pour avoir des performances sera bel et bien le parallélisme. Et c'est bien ça le problème,  bien que nous possédions déjà le parallélisme de tâches grâce aux webworkers, il nous manque encore le parallélisme de données  ou quelque chose d'encore plus évolué (genre SPMD ). Certains me dirons que ce dernier sera géré en partie par rivertrail.  A ceci, je répondrai seulement que l'API est relativement restrictive et que je préférerai une approche plus proche d'OpenCL/Cuda :  j'aurais adoré voir asm.js exécuté sur GPU ou CPU au choix, avec un « hint » pour le compilateur, surtout que passer le sous-ensemble MIR/LIR d'ASM.js en code C pour GPU est relativement simple. J'aurais aussi aimé que les typedArray qui sont utilisés comme arguments soient la mémoire globale (CPU ou GPU) avec de simples mutex et que le compilateur soit capable de gérer les heaps comme des caches bas niveaux (un peu comme la mémoire privé d'OpenCL ou les registers en C)….

Concrètement, c'est faisable?

Techniquement, cela n'est pas très difficile à réaliser[1] mais avec l'évolution envisagée qui est de dire qu'asm.js doit faire de plus en plus de choses et ne pas rester si limité comme sous-ensemble du javascript, je crains que ce ne soit qu'un vœu pieu (avec par exemple les pointeurs de fonctions qui ne sont pas possibles sur tout les GPU sans créer une sorte de vtable à la main). C'est un point que je comprends d'autant moins que le but du projet était bien d'avoir un sous-ensemble du javascript le plus optimisé possible tout en gardant l'aspect sécurisé de ce dernier, bien entendu.
Tiens, tant qu' à rêver, pourquoi ne pas avoir, un jour, un code javascript capable de faire de l’auto-vectorisation si rapide que l’exécutable serait plus rapide que celui compilé par GCC grâce au parallélisme et cela, sans même que le développeur n'ait rien à faire ( comme avec sumatra )

[1] On parle ici de prendre le code assembleur généré par le moteur javascript, d'avoir quelques hooks sur les fonctions essentielles (math/ threadid…) et de lancer cela à partir d'un threadPool. Après il faut aimer bidouiller dans le moteur js, mais ce n'est pas si difficile (regarder pour comprendre comment ajouter des API et ceci pour voir comment utiliser le code natif -> cela n'est pas plus compliqué que ce que l'on trouve ailleurs. En plus, cela permettrait de mutualiser avec ce qui pourrait être fait pour WebCL, non? Bon mais c'est un peu fastidieux à faire et pas le plus sexy à faire avant de dormir).
Allez dés que je trouve le temps (probablement pas avant quelques semaines), je fais un prototype.

Un avis sur le sujet? Quelqu'un qui serait intéressé?

  • # Ah ouais carrément!

    Posté par . Évalué à 4.

    hello,

    pourquoi ne pas transformer ce post en journal ?
    Je me dit que sa visibilité sera bien meilleure et les retours plus nombreux.

    Le sujet m’intéresse beaucoup, c'est un peu bas niveau pour moi, mais je sais que j'ai matière à en apprendre.
    En plus tu as la plume agréable à lire.

    En tout cas j'accroche à ton discours à 200%.
    Une approche qui ne casse pas l'existant mais l'améliore, sans dénaturer le JS.
    En une phrase, Faudrait être ocn pour passer à côté.

    Je surveillerais cela de plus près, merci !

    a+

Suivre le flux des commentaires

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