90 votes

Taille de la ligne des caches L1 et L2

D'après un précédent question Sur ce forum, j'ai appris que dans la plupart des systèmes de mémoire, le cache L1 est un sous-ensemble du cache L2, ce qui signifie que toute entrée retirée de L2 est également retirée de L1.

Maintenant ma question est de savoir comment déterminer une entrée correspondante dans le cache L1 pour une entrée dans le cache L2. La seule information stockée dans l'entrée L2 est l'information du tag. Sur la base de ces informations, si je recrée l'adresse, elle peut couvrir plusieurs lignes dans le cache L1 si les tailles de ligne des caches L1 et L2 ne sont pas les mêmes.

L'architecture se soucie-t-elle vraiment de vider les deux lignes ou maintient-elle simplement les caches L1 et L2 avec la même taille de ligne ?

Je comprends qu'il s'agit d'une décision politique mais je veux connaître la technique couramment utilisée.

92voto

Axel Borja Points 1619

La taille des lignes de cache est (généralement) de 64 octets.

Par ailleurs, jetez un coup d'œil à cet article très intéressant sur les caches des processeurs : Galerie des effets du cache du processeur

Vous trouverez les chapitres suivants :

  1. Accès à la mémoire et performances
  2. Impact des lignes de cache
  3. Taille des caches L1 et L2
  4. Parallélisme au niveau des instructions
  5. Associativité du cache
  6. Faux partage des lignes de cache
  7. Complexité du matériel

90voto

Neha Karanjkar Points 806

Dans le Core i7, la taille des lignes de L1, L2 et L3 est la même, soit 64 octets. Je suppose que cela simplifie le maintien de la propriété inclusive et de la cohérence.

Voir la page 10 de : https://www.aristeia.com/TalkNotes/ACCU2011_CPUCaches.pdf

26voto

Paul A. Clayton Points 3415

La technique la plus courante pour gérer la taille des blocs de cache dans une hiérarchie de cache strictement inclusive consiste à utiliser des blocs de cache de même taille pour tous les niveaux de cache pour lesquels la propriété d'inclusion est appliquée. Cela entraîne un surdébit de balises plus important que si le cache de niveau supérieur utilisait des blocs plus grands, ce qui non seulement utilise de la surface de puce mais peut également augmenter la latence puisque les caches de niveau supérieur utilisent généralement un accès progressif (où les balises sont vérifiées avant l'accès à la partie données). Cependant, cela simplifie quelque peu la conception et réduit le gaspillage de capacité dû aux parties inutilisées des données. Il n'est pas nécessaire d'utiliser une grande partie des morceaux de 64 octets inutilisés dans les blocs de cache de 128 octets pour compenser la pénalité de surface d'une étiquette supplémentaire de 32 bits. En outre, l'effet d'un bloc de cache plus grand, qui permet d'exploiter une plus grande localité spatiale, peut être obtenu par une préextraction relativement simple, qui présente les avantages suivants : aucune capacité n'est inutilisée si le bloc voisin n'est pas chargé (pour économiser la bande passante de la mémoire ou réduire la latence d'une lecture de mémoire conflictuelle) et la préextraction par contiguïté ne doit pas nécessairement être limitée à un bloc aligné plus grand.

Une technique moins courante consiste à diviser le bloc de cache en secteurs. Le fait que la taille du secteur soit la même que celle du bloc pour les caches de niveau inférieur évite le problème de la rétro-invalidation excessive puisque chaque secteur du cache de niveau supérieur a son propre bit valide. (Le fait de fournir toutes les métadonnées d'état de cohérence pour chaque secteur plutôt que la seule validité peut éviter l'utilisation excessive de la bande passante de writeback lorsqu'au moins un secteur d'un bloc n'est pas sale/modifié et une certaine surcharge de cohérence [par exemple, si un secteur est dans l'état partagé et un autre dans l'état exclusif, une écriture dans le secteur dans l'état exclusif pourrait n'impliquer aucun trafic de cohérence - si la cohérence snoopy plutôt que la cohérence de répertoire est utilisée]).

Les économies de surface réalisées grâce aux blocs de cache sectorisés étaient particulièrement importantes lorsque les étiquettes se trouvaient sur la puce du processeur mais que les données étaient hors puce. Évidemment, si le stockage des données occupe une surface comparable à la taille de la puce du processeur (ce qui n'est pas déraisonnable), alors les étiquettes 32 bits avec des blocs de 64 octets occuperaient environ un 16e (~6 %) de la surface du processeur, tandis que les blocs de 128 octets en occuperaient la moitié. (Le POWER6+ d'IBM, introduit en 2009, est peut-être le processeur le plus récent à utiliser des balises sur la puce du processeur et des données hors-processeur. Le stockage des données dans la DRAM intégrée à haute densité et des balises dans la SRAM à plus faible densité, comme l'a fait IBM, exagère cet effet).

Il convient de noter qu'Intel utilise le terme "ligne de cache" pour désigner la petite unité et le terme "secteur de cache" pour la grande unité. (C'est l'une des raisons pour lesquelles j'ai utilisé le terme "bloc de cache" dans mon explication). En utilisant la terminologie d'Intel, il serait très inhabituel que les lignes de cache varient en taille entre les niveaux de cache, que les niveaux soient strictement inclusifs, strictement exclusifs ou qu'ils utilisent une autre politique d'inclusion.

(L'exclusion stricte utilise généralement le cache de niveau supérieur comme un cache victime où les évictions du cache de niveau inférieur sont insérées dans le cache de niveau supérieur. De toute évidence, si la taille des blocs était différente et que la sectorisation n'était pas utilisée, une éviction nécessiterait la lecture du reste du bloc le plus grand à partir d'un endroit quelconque. y invalidé s'il est présent dans le cache de niveau inférieur. [ Théoriquement L'exclusion stricte peut être utilisée avec un contournement inflexible de l'antémémoire, où une éviction de L1 contournerait L2 et irait à L3, et où les manques d'antémémoire de L1/L2 ne seraient attribués qu'à soit L1 or L2, contournant L1 pour certains accès. Le cas le plus proche de cette implémentation que je connaisse est le contournement de L1 par Itanium pour les accès en virgule flottante ; cependant, si je me souviens bien, la L2 était incluse dans L1.])

1voto

RD Bhattacharya Points 31

En général, en un seul accès à la mémoire principale, on accède à 64 octets de données et 8 octets de parité/ECC (je ne me souviens plus exactement lesquels). Et il est assez compliqué de maintenir différentes tailles de lignes de cache aux différents niveaux de la mémoire. Il faut noter que la taille de la ligne de cache est plus corrélée à la taille de l'alignement des mots sur cette architecture qu'à toute autre chose. Sur cette base, il est très peu probable que la taille d'une ligne de cache soit différente de la taille d'accès à la mémoire. Les bits de parité sont à l'usage du contrôleur de mémoire - la taille de la ligne de cache est donc généralement de 64 octets. Le processeur contrôle vraiment très peu de choses en dehors des registres. Tout le reste se passe dans l'ordinateur et consiste plutôt à intégrer du matériel pour optimiser les performances du processeur. En ce sens également, il ne serait vraiment pas judicieux d'introduire une complexité supplémentaire en faisant varier la taille des lignes de cache selon les niveaux de mémoire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X