• [^] # Re: Et les compilateurs?

    Posté par . En réponse à la dépêche Kalray un processeur massivement parallèle très impressionnant : Qu’il est loin le temps de mon ZX81. Évalué à 8.

    Pour aller dans ton sens : je l'ai déjà dit ailleurs, mais les deux « gros » compilateurs pour Itanium 2 sont icc et gcc. Le premier a mis deux ou trois générations avant de générer du code ultra optimisé (à partir d'icc v9.1 en gros, le code devient vraiment bon, avec une bonne exploitation des techniques de pipeline logiciel, la if-conversion, etc.). Le deuxième (gcc donc) génère du code entre deux et dix fois plus lent qu'icc. Pourtant, le modèle machine est bien mieux décrit pour IA64 que pour x64 ou ia32 (c'est nécessaire, vu que le compilateur doit générer tout le code statiquement).

    Et en fait, si on regarde les techniques proposées pour accélérer le code sur VLIW, on trouve tout un tas de « contournements » de l'aspect statique pour la génération de code. On peut citer par exemple les techniques de « trace scheduling » (trop complexe à implémenter la plupart du temps) et surtout de « superblocks » et « hyperblocks ». L'idée derrière tout ça est de faire de la compilation guidée par profilage (profile guided optimization) :

    1. On compile une première version du binaire et on l'exécute sur un petit jeu d'entrées représentatives.
    2. Après avoir instrumenté l'exécution de ce mini-run, on recompile le code en y ajoutant des annotations.
    3. Durant la compilation, on va générer plusieurs versions du « chemin chaud » (hou, je préfère la V.O. : « hot path »), ou si on préfère un autre terme, du « chemin critique » en termes de temps passé à calculer. L'idée est de profiter des capacités de spéculation sur les données et sur le contrôle de l'Itanium pour statiquement prédire « prise » l'une ou l'autre branche d'un if/else. La plupart du temps, si le code n'est pas trop irrégulier niveau contrôle, la spéculation sera une chose positive. Pour les rares cas où ça ne l'est pas, on doit rebrancher sur le code original, et « rejouer » toute la partie de code qui avait été spéculée. Évidemment, si on ne se trompe que de temps en temps, le surcoût est négligeable. Si on a mal effectué le profilage, ou si le code est trop irrégulier (ce qui est le cas des codes type compression de donnée, dont le comportement dépend fortement des entrées par exemple), cette optimisation va ruiner les performances.
    4. La techniques des hyperblocks est similaire à celle des superblocks, mais rajoute en plus la if-conversion (et là, je renvoie à un truc que j'avais écrit cet été en promettant une suite pour « bientôt » — haha, la bonne blague).

    Bref, bien qu'il existe tout un tas de techniques de compilations pour statiquement utiliser au maximum les unités fonctionnelles d'un processeur (VLIW ou pas), ces dernières ont toutes des désavantages liés au fait qu'il faut faire du profilage de code sur tout un tas d'entrées différentes pour avoir une optimisation qui marche « au mieux » dans le cas moyen. Les gens de Firefox (ou Chrome, ou...) peuvent le faire en partie grâce aux informations remontées par les PC d'utilisateurs qui indiquent quel genre de pages ils visitent, etc., ce qui fait que les fermes de compilation peuvent prendre en compte ce genre de trucs, et effectuer de la PGO (profile-guided optimization). À moins de faire de même pour tous les softs utilisés (avec les risques liés à la vie privée que cela comporte, sans parler du flux constant d'information qui ira vers le net et qui accompagnera toute exécution de n'importe quel soft — y compris ls ? ;-) ), ça risque d'être un peu compliqué.