AMD K8 - Partie 3 : Etude de l'Architecture | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
By Franck D. - 16/02/2003 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Etude des caches :
Les caches L2 des K7 et K8 partagent de nombreuses caractéristiques, notamment une associativité à 16 voies qui permet de compenser en partie l'associativité deux voies du cache L1. Le bus d'échange entre le noyau et le cache L2 passe de 64 bits
sur K7 à 128 bits sur le K8, ce qui devrait permettre une augmentation
du débit du cache L2. Sur le K7, ce bus a été dimensionné
en tenant compte des spécificités des caches L2 des premiers
Athlon à cache externe, et commence a montrer ses limites sur les
modèles à cache intégré. L'augmentation de
la largeur du bus devrait avoir un impact direct sur le débit du
cache L2, ce que nous ne manquerons pas de vérifier. Une des caractéristiques les plus marquantes du cache L2 des K7 et K8 est sa relation exclusive avec le cache L1, ce qui les distingue des processeurs Intel qui adoptent une relation de type inclusive. L'occasion se présente donc d'expliquer en quoi ces deux modes de fonctionnement se distinguent dans la pratique, ainsi que de connaître les points forts et les points faibles de chaque système.
Afin de bien comprendre le fonctionnement d'un cache, considérons le cas hypothétique d'un processeur possédant un seul niveau de cache. Lorsqu'arrive une requête en lecture, le processeur va interroger son cache. Si la donnée ne s'y trouve pas, il va alors la chercher en mémoire, et en même temps qu'elle y est récupérée elle est copiée dans le cache. Pourquoi cela ? car le processeur suppose que s'il a eu besoin de cette donnée, il en aura encore besoin sous peu. Un processeur x86 possède peu de registres, et la valeur récupérée qui se trouve alors dans un registre n'y restera pas plus de quelques cycles ; la stocker dans le cache permettra ainsi au besoin de la récupérer rapidement. Avec un niveau de cache, une requête en lecture du processeur se traduit par deux états possibles :
Figure 1 : mise en cache
La chose se complique lorsque le cache est plein, car alors la mise en cache nécessite de remplacer une ligne déjà occupée. Afin de choisir quelle ligne va être évincée, le processeur se base sur un algorithme de remplacement, le choix le plus courant consistant à remplacer la ligne la moins récemment utilisée ; c'est l'algorithme LRU, pour Least Recently Used.
Figure 2 : Eviction d'une ligne de cache
L'ajout d'un second niveau de cache se traduit par des états supplémentaires lors d'une requête en lecture :
Lorsque le cache L1 n'est pas plein, la phase de mise en cache est similaire à la configuration à un seul niveau : Figure 3 : mise en cache Ce n'est que lorsque le L1 est plein que le cache L2 a un rôle actif : lorsqu'une ligne est évincée du L1, celle-ci est stockée dans le L2, et une nouvelle ligne issue de la mémoire occupe la place ainsi libérée dans le L1 :
Figure 4 : Remplissage du L2 Dès ce moment, le cache L2 contient des données et est susceptible de répondre positivement à une requête de lecture. Dès lors, si la donnée recherchée n'est pas trouvée dans le L1 mais l'est dans le L2, une ligne doit être libérée dans le L1 afin d'accueillir la ligne issue du L2. La ligne évincée est copiée dans un emplacement libre du L2, puis la ligne concernée du L2 est remontée dans le L1 et invalidée dans le L2 afin de libérer de la place :
Figure 5 : Echec du L1, succès du L2 Dans ce mode de fonctionnement, on remarque qu'une ligne de cache n'existe jamais conjointement dans les deux niveaux mais qu'elle passe de l'un à l'autre, plusieurs fois si nécessaire. Les caches n'interfèrent pas, et une donnée se trouve exclusivement dans l'un des deux niveaux : c'est un cache exclusif. La taille totale du cache efficace est donc égale à la somme des tailles des deux niveaux. De plus, aucune contrainte de taille n'existe entre les deux niveaux de cache, le système fonctionne même si le cache de second niveau est d'une taille inférieure au premier niveau. La relation exclusive permet ainsi une grande souplesse, mais elle présente
un inconvénient en terme de performances : en effet, en cas de
succès en lecture dans le cache L2, une ligne du L1 doit y être
écrite avant de récupérer la donnée depuis
le L2. Cette écriture est assez pénalisante en terme de
cycles et ralentit le temps total de récupération depuis
le L2. Le VB présente une bonne amélioration du mode exclusif, mais son intérêt est limité par sa taille bien souvent assez réduite (d'une dizaine d'entrées en général). Qui plus est, lorsque le VB est plein, les lignes qu'il contient sont mises à jour dans le cache L2, ce qui représente une phase supplémentaire dans le traitement. Pour terminer, la présence du VB accélère la phase d'écriture, mais ne la supprime pas pour autant. Réfléchissons quelques instants : pour éviter cette phase d'écriture dans le L2 en cas d'éviction, il faudrait que la donnée à évincer soit déjà dans le cache L2. Comment cela est-il possible ? Il suffit en fait de copier la donnée dans le L2 lors de la phase de mise en cache. Voyons cela : Dans cette configuration, lorsqu'une donnée est remontée depuis la mémoire centrale elle est copiée dans le L1 et dans le L2. En ce sens, la mise en cache nécessite une copie supplémentaire par rapport au mode exclusif.
Figure 6 : Mise en cache Lorsque le L1 est plein et que la donnée demandée ne se
trouve ni dans le L1 ni dans le L2 (échec L1, échec L2),
une nouvelle ligne est copiée depuis la mémoire dans les
deux niveaux. La ligne remplacée dans le L1 n'est pas sauvée
dans le L2 car elle s'y trouve déjà. On a donc le même
nombre de copies par rapport à la même opération dans
le mode exclusif.
Figure 7 : Echec L1 et L2 Lorsque la donnée n'est pas trouvée dans le L1 mais l'est dans le L2 (échec L1, succès L2), la seule opération consiste à remplacer une ligne de cache du L1 par une ligne du L2. On économise ainsi l'écriture de la ligne évincée dans le L2.
Figure 8 : Echec L1 et succès L2 Dans ce mode de fonctionnement, toutes les lignes présentes à
chaque instant dans le L1 sont également dans le L2, ce qui revient
à dire que le L2 inclut une image du L1. C'est le mode inclusif.
Résumons les points forts et les points faibles d'un cache exclusif :
Considérant cela, on peut établir ce à quoi il doit ressembler pour fournir les performances maximales :
AMD utilise un cache L2 exclusif sur la gamme K7 depuis le Thunderbird.
L'architecture du processeur est conforme à un tel choix avec un
cache L1 de grande taille (deux fois 64 Ko). AMD a également recours
à un victim buffer à 8 entrées. En comparaison, le cache inclusif présente les avantages et inconvénients suivants :
L'avantage du mode inclusif réside avant tout dans les performances
qu'il procure, à condition bien sûr que les contraintes que
nous avons évoquées soient respectées. Intel a pris le pari du mode inclusif depuis le Pentium Pro. En conséquence,
aucun processeur de cette gamme (et des suivantes) n'a eu un cache L1
de grande taille, et pour cause. La plus grande taille de L1 est atteinte
avec le Pentium M (2 fois 32Ko), mais celui-ci est secondé par
un cache L2 de 1Mo ! Avec l'avénement du Pentium 4, Intel a même
diminué la taille du L1, avec seulement 8 Ko pour le cache de données.
Choix risqué, mais finalement logique : quitte à avoir un
cache de petite taille, autant le faire tout petit, mais très rapide.
Le L1 du Pentium 4 est en revanche le plus rapide qui soit, avec une latence
d'accès de 2 cycles. Le mode inclusif permet au cache L2 de combler
la faible taille du L1.
Le choix d'un système de cache inclusif ou exclusif représente un choix important dans le design d'un processeur. Il conditionne les performances, mais également l'évolutivité vers les deux extrêmes de gamme. Le mode exclusif est le plus flexible, au détriment de performances optimales que seul le mode inclusif peut atteindre. En revanche, ce mode souffre de nombreuses contraintes, et ne pas les respecter peut avoir l'effet inverse recherché, à savoir une perte de performances.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Fermer |