• [^] # Re: Je maintiens qu'il y a une partie qui n'est pas terrible

    Posté par . En réponse à la dépêche Où vont les supercalculateurs ? D’où on vient, quels sont les problèmes, où l’on va (1re partie). Évalué à 10.

    La seule partie « CISC » du x86 est le couple fetch-decode du front-end. Pour les processeurs jusqu'à la micro-architecture Nehalem (6 pour Sandy Bridge et aussi sans doute Ivy Bridge, mais je n'ai pas suivi), le décodeur a quatre ports (considère ça comme des entrées) : le premier décode toutes les instructions CISC de 1 octet ou plus; les trois autres s'occupent d'instructions de 1 octet très exactement. Une fois le décodage effectué, tout le reste est bel et bien résolu comme pour une machine RISC classique. Il y a longtemps (plus de 10 ans), mon prof d'architecture appelait ça du « CRISC » : front-end CISC (étages IF et ID du pipeline), mais back-end RISC (tous les autres étages). Pour un processeur de type Pentium III ou Pentium 4, ça veut dire qu'environ 17% du temps est passé dans un module « CISC » (dans mes souvenirs le PIII avait 12 étages), et environ 6% pour le P4. En pratique comme les core 2 et suivants sont des évolutions du PIII, on peut toujours considérer que ~16-17% est passé dans le front-end.

    Dire que le coeur x86 a derrière un RISC bof, ça n'a pas grand sens:
    1) déjà c'est un jeu d'instruction qui est visible uniquement en interne: le compilateur n'y a pas accès. [...]

    C'est vrai.

    Ce qui pose des contraintes par exemple pour l'accès aux registres: le compilateur peut-être obligé d'écrire un registre x86 en mémoire pour faire de la place alors que le CPU a bien assez de registres physiquement présent, mais ils sont cachés et inaccessible directement..

    Je suis d'accord pour x86 non 64 bits (où on n'avait en gros que 15 registres adressables). À partir du moment où tu peux utiliser rax, rbx, ..., r15, et en plus de cela tu peux aussi utiliser les xmm0, ..., xmm15 comme s'il s'agissait de registres scalaires, tu as bien 32 registres. Je n'ai pas les références en tête, mais en gros, il a été montré qu'avec les heuristiques actuelles pour l'allocation de registres et l'ordonnancement d'instructions, sauf à avoir des codes vraiment très réguliers (donc typiquement du HPC ;-)), on n'exploitait pas correctement les registres et les solutions d'allocation sont souvent sub-optimales (ce qui est « normal » en soit : l'ordonnancement des instructions et l'allocation des registres sont deux problèmes NP-complets).

    2) les micro instructions suivent-elle vraiment les principes du RISC [...]

    Oui. Là-dessus il n'y a absolument pas de doute possible.

    Il faut bien comprendre qu'avant l'introduction de RISC, la seule façon (à ma connaissance) de garantir une instruction par cycle était à travers les processeurs vectoriels, tels que le (mythique) Cray-I. C'est-à-dire : on garantit que deux longs vecteurs de données (pour le Cray-I, il faut compter 2 vecteurs de 32 mots maximum chacun) sont chargés en mémoire. Ensuite on applique la même opération (+, -, etc.) sur deux mots (un de chaque vecteur), et on stocke le résultat quelque part pour chaque cycle. Bref, on garantit que les opérandes seront disponibles cycle après cycle pendant n cycles (32 par ex.). Comme on pouvait « chaîner » certaines opérations (multiplications puis additions par exemple), on pouvait gagner énormément de temps au final. Ici il s'agissait plus d'une sorte de « pipeline mémoire » que d'un pipeline d'instruction au final. Un système de masquage de bits permettait aussi de gérer les branchements conditionnels tant qu'au final une opération vectorielle allait s'effectuer.

    Ce qu'a apporté le RISC comparé aux processeurs vectoriels, c'est la possibilité d'effectuer des instructions différentes cycle après cycle, et garantir qu'en moyenne, on aura bien un débit proche de une instruction par cycle (certes, grâce à un programmeur très compétent, ou un compilateur très intelligent).

    Enfin, je vais donner un argument d'autorité :

    les micro instructions suivent-elle vraiment les principes du RISC [...] peut-être, peut-être pas, vous avez la doc d'Intel vous?

    J'ai the next best thing : j'ai bossé (et je continue de bosser) avec Intel. Je ne suis pas un employé par contre. J'ai passé quelques années à faire des micro-benchmarks pour caractériser les architectures Intel (Core 2, Nehalem en particulier), et ça passait entre autres par des trucs du genre « faire des programmes "RISC" en x86 », « utiliser des instructions exotiques que personne n'utilise », « utiliser des instructions que le compilateur utilise souvent (genre lea) », etc.

    Ensuite, la page wikipedia (langue anglaise) n'est pas sourcée lorsqu'elle affirme que derrière le front-end, on a un moteur RISC. AnandTech est d'accord avec moi et Wikipedia cependant, et d'un point de vue très pratique, faire un pipeline qui n'accepte pas des mots de taille identique est quelque chose d'assez compliqué à réaliser (et les bénéfices en termes de performance peuvent être éclipsés par l'énergie nécessaire pour mettre en œuvre ce genre de solution).

    Ce n'est pas pour dire qu'il n'y a pas des optimisations possibles pour la partie CISC du processeur. Si tu vas sur le site d'Agner, tu verras qu'il décrit plutôt bien la façon dont les pipelines des différents processeurs sont réalisés. Il existe des mécanismes de « macro-fusion » qui permettent de « factoriser » certains traitements pour accélérer le décodage des instructions, etc.