• # Comment faire un langage plus rapide que C ?

    Posté par (site web personnel) . En réponse à la dépêche 23 mars: Conférence au LORIA sur Lisaac, un nouveau langage. Évalué à 6.

    Un débat confus émerge, et nicO a abordé ce point sur la news. C'est un sujet important, en particulier pour lui qui nous bombarde d'excellentes idées pour optimiser le code.

    Comment cela peut être possible ?

    Premier point : Le minimalisme du code.

    Le langage Lisaac est basé sur 7 primitives (elles sont définies dans le manuels, on les trouve aussi dans la librairie sous la forme `1`).
    Ce nombre minimaliste permet au compilateur de travailler sur un code intermédiaire extrêment minimaliste et dépouillé.
    C'est nécessaire pour réaliser l'ensemble des optimisations.

    Second point : La suppression de la liaison dynamique

    Je reprend ce que j'ai écrit sur Wikipedia :
    Les langages objets classiques, jusqu'à SmartEiffel, utilisent des VFTs (de l'anglais Virtual Function Table) pour compiler la liaison dynamique: :

    Soient l'objet IMAGE, et ses deux descendants PNG et XCF. Quand on appelle la fonction PNG.affiche_toi() en Java ou en C++, on se retrouve en assembleur avec un appel du type :

    Call dword ptr [__adresse_de_PNG + index_dans la_VFT_de_la_fonction_affiche_toi()]

    L'adresse de PNG (l'objet receveur) pointe sur la base de la VFT, ensuite on ajoute le bon index pour recuperer le champs correspondant à la bonne methode...

    Ce qui implique que cela vide le cache du processeur et que l'inlining est bloqué à la compilation.

    Le compilateur lisaac supprime la liaison dynamique en analysant finement le type dynamique des objets grâce à un algorithme de prédiction de type. La liaison dynamique supprimée, il devient possible de procéder à des inlining et à des spécialisations de code.


    Je devrai y rajouter que le polymorphisme se gère en utilisant une table duchotomique, ce qui implique que la recherche se fait en log de n.
    Cela permet surtout d'avoir un code entièrement procédurale, sans dynamicité pour tuer les performances.

    Troisième point : L'analyse de flot
    Comme vous le savez pour la plupart d'entre vous, l'analyse de flot est une technique qui permet d'analyser le code (son graphe) pour y trouver diverses choses.
    Le compilateur Lisaac réalise le graphe de l'ensemble du code, c'est pour cela que compiler 40 000 lignes (libraririe comprise) prend avec ce compilateur 512 Mo de mémoire.
    C'est un algo de complexité exponentielle, ce qui est risqué pour des programme de taille plus ample.

    L'analyse de flot va par exemple permettre de détecter que l'on ait par exemple n := n*2+1; quelque part et que dans une autre méthode, "10 km plus loin" on fasse un (n mod 2).if
    Dans ce cas le test est supprimé.
    Ce n'est pas encore implémenté car trop gourmand en mémoire (4 Go pour 400 lignes hors librairie).

    Pour le moment, le compilateur recence le code vivant, supprime toutes les étapes inutiles, supprime le code mort, spécialise les types.

    L'analyse de flot permet, par reconnaissance de forme, de transformer des structures lourdes en structures légère.
    Par exemple le message if, initialement, est écrit comme suit (en C):
    if(id_obj) { /*V*/}
    else
    if (!id_obj) { /*F*/}

    transformé en if (id_obj) { /*V*/} else { /*F*/}

    de même les récurcivité terminale sont dérécurcivées.

    Dans le futur, on peut pense à des techniques d'optimisation de la mémoire, pour se coller à la structure du cache, ou des techniques permettant de gérer automatiquement les threads, ou encore des techniques permettant de spécialiser des corps de calculs en fonction des données.
    Ce dernier point vous sera mieux expliqué par nicO qui développe en ce moment ces idées.

    « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker