Je me souviens d’avoir supposé qu’un accès au cache L1 correspond à un cycle (c’est-à-dire identique au temps d’accès au registre) dans ma classe d’architecture, mais est-ce réellement le cas sur les processeurs x86 modernes?
Combien de cycles dure une mise en cache L1? Comment se compare-t-il pour enregistrer un accès?
Voici un excellent article sur le sujet:
http://arstechnica.com/gadgets/reviews/2002/07/caching.ars/1
Pour répondre à votre question - oui, un accès en mémoire cache a approximativement le même coût qu'un accès au registre. Et bien sûr, un cache cache est assez coûteux;)
PS:
Les détails varieront, mais ce lien a quelques bons chiffres approximatifs:
Coût approximatif pour accéder à divers caches et à la mémoire principale?
Core i7 Xeon 5500 Series Data Source Latency (approximate)
L1 CACHE hit, ~4 cycles
L2 CACHE hit, ~10 cycles
L3 CACHE hit, line unshared ~40 cycles
L3 CACHE hit, shared line in another core ~65 cycles
L3 CACHE hit, modified in another core ~75 cycles remote
L3 CACHE ~100-300 cycles
Local DRAM ~30 ns (~120 cycles)
Remote DRAM ~100 ns
PPS:
Ces chiffres représentent beaucoup processeurs plus lents et plus anciens, mais les ratios sont essentiellement les suivants:
http://arstechnica.com/gadgets/reviews/2002/07/caching.ars/2
Level Access Time Typical Size Technology Managed By
----- ----------- ------------ --------- -----------
Registers 1-3 ns ?1 KB Custom CMOS Compiler
Level 1 Cache (on-chip) 2-8 ns 8 KB-128 KB SRAM Hardware
Level 2 Cache (off-chip) 5-12 ns 0.5 MB - 8 MB SRAM Hardware
Main Memory 10-60 ns 64 MB - 1 GB DRAM Operating System
Hard Disk 3M - 10M ns 20 - 100 GB Magnetic Operating System/User
Pour plus de détails sur le comptage de cycles et l'exécution dans le désordre, voir le microarch pdf d'Agner Fog , et d'autres liens dans le x86 tag wiki .
La latence d'utilisation de la charge L1 d'Intel Haswell est de 4 cycles, ce qui est typique des processeurs x86 modernes. c'est-à-dire à quelle vitesse mov eax, [eax]
peut s'exécuter en boucle, avec un pointeur qui pointe vers lui-même. (Ou à une petite liste chaînée en boucle fermée).
La latence d'utilisation de la charge est supérieure d'un cycle pour les vecteurs SSE/AVX dans les processeurs Intel.
La latence de rechargement du magasin est de 5 cycles et n'a aucun lien avec le cache ou le manque du cache (c'est le transfert de magasin, pas le cache L1).
Comme l'a commenté harold, l'accès aux registres est égal à 0 cycle. Donc, par exemple:
inc eax
a une latence de cycle (juste l'opération ALU)inc dword [mem]
a une latence de 6 cycles jusqu'à ce qu'une charge de dword [mem]
soit prête. (ALU + transfert de magasin). par exemple. garder un compteur de boucle en mémoire limite une boucle à une itération sur 6 cycles.mov rax, [rsi]
a une latence sur 4 cycles de rsi
étant prêt à rax
sur un hit L1 (latence d'utilisation de la charge L1).http://www.7-cpu.com/cpu/Haswell.html a un tableau des latences par cache (que je vais copier ici), ainsi que d’autres numéros expérimentaux, y compris la latence des hits L2-TLB ( sur une miss L1DTLB).
Intel i7-4770 (Haswell), 3,4 GHz (Turbo Boost off), 22 nm. RAM: 32 Go (PC3-12800 cl11 cr2).
- Cache de données L1 = 32 Ko, 64 B/ligne, 8 VOIES.
- Cache d’instruction L1 = 32 Ko, 64 B/ligne, 8 VOIES.
- Cache L2 = 256 Ko, 64 B/ligne, 8 VOIES
Cache L3 = 8 Mo, 64 B/ligne
Latence du cache de données L1 = 4 cycles pour un accès simple via un pointeur (
mov rax, [rax]
)- L1 Data Latency Latency = 5 cycles d'accès avec calcul d'adresse complexe (
mov rax, [rsi + rax*8]
).- Latence du cache L2 = 12 cycles
- Latence du cache L3 = 36 cycles
- Latence RAM = 36 cycles + 57 ns
La page de référence de niveau supérieur est http://www.7-cpu.com/utils.html , mais n'explique toujours pas vraiment la signification des différentes tailles de test, mais le code est disponible. Les résultats du test incluent Skylake , qui est presque identique à Haswell dans ce test.
La réponse de @ paulsm4 a une table pour un Nehalem Xeon multi-socket, y compris des numéros de mémoire/L3 distants (autre-socket).
Si je me souviens bien, c'est environ 1 à 2 cycles d'horloge, mais il s'agit d'une estimation et les nouveaux caches peuvent être plus rapides. Ceci est tiré d'un livre d'architecture d'ordinateur que j'ai et c'est une information pour AMD, donc Intel peut être légèrement différent, mais je le liais entre 5 et 15 cycles d'horloge, ce qui me semble être une bonne estimation.
EDIT: Whoops L2 est 10 cycles avec accès TAG, L1 prend 1 à 2 cycles, mon erreur: \
En réalité, le coût du résultat de cache N1 est presque identique à celui d'un accès à un registre. C'était surprenant pour moi, mais c'est vrai, du moins pour mon processeur (Athlon 64). Il y a quelque temps, j'ai écrit une application de test simple pour évaluer l'efficacité de l'accès aux données partagées dans un système multiprocesseur. Le corps de l'application est une simple variable de mémoire incrémentée pendant la période prédéfinie. Pour faire une comparaison, j'ai d'abord comparé les variables non partagées. Et au cours de cette activité, j'ai capturé le résultat, mais lors du désassemblage de l'application, j'ai constaté que le compilateur avait déçu mes attentes et appliqué une optimisation non souhaitée à mon code. Il suffit de mettre la variable dans le registre de la CPU et de l’incrémenter de manière itérative dans le registre sans accès à la mémoire. Mais la vraie surprise a été atteinte après avoir forcé le compliler à utiliser une variable en mémoire au lieu d'une variable de registre. Lors de la mise à jour de l’application, j’ai obtenu à peu près les mêmes résultats. La dégradation des performances était vraiment négligeable (~ 1-2%) et semble liée à un effet secondaire.
À la suite:
1) Je pense que vous pouvez considérer le cache L1 comme un pool de registres de processeurs non administrés.
2) Il n’ya aucune raison d’appliquer une optimisation brutale en obligeant le compilateur à stocker fréquemment les données dans les registres du processeur. S'ils sont très fréquemment consultés, ils vivront dans le cache L1 et, à cause de cela, auront le même coût d'accès que le registre du processeur.