Caché jerárquico - Enciclopedia

Estructura de caché, o caché de múltiples niveles, es una arquitectura de memoria que utiliza una jerarquía de almacenes de memoria basada en diferentes velocidades de acceso para almacenar datos. Los datos altamente solicitados se almacenan en almacenes de acceso rápido, permitiendo un acceso más rápido por parte de los núcleos del procesador (CPU).

La estructura de caché es una forma y parte de la jerarquía de memoria y puede considerarse una forma de almacenamiento en capas. Este diseño tenía la intención de permitir que los núcleos del CPU procesen más rápidamente a pesar de la latencia de acceso a la memoria principal. Acceder a la memoria principal puede actuar como una garganta de botella para el rendimiento del núcleo del CPU, ya que el CPU espera los datos, mientras que hacer que toda la memoria principal sea de acceso rápido puede ser prohibitivamente caro. Las cachés de alta velocidad son un compromiso que permite un acceso rápido a los datos más utilizados por el CPU, permitiendo una frecuencia de reloj del CPU más rápida.


Antecedentes
En la historia del desarrollo de computadoras y chips electrónicos, hubo un período en el que los aumentos en la velocidad del CPU superaron las mejoras en la velocidad de acceso a la memoria. La brecha entre la velocidad de los CPU y la memoria significaba que el CPU a menudo estaba inactivo. Los CPU eran cada vez más capaces de ejecutar y ejecutar cantidades más grandes de instrucciones en un tiempo dado, pero el tiempo necesario para acceder a los datos desde la memoria principal prevenía que los programas aprovecharan plenamente esta capacidad. Este problema motivó la creación de modelos de memoria con tasas de acceso más altas para realizar el potencial de los procesadores más rápidos.
Esto resultó en el concepto de caché de memoria, primero propuesto por Maurice Wilkes, un científico informático británico en la Universidad de Cambridge en 1965. Llamó a estos modelos de memoria "memoria esclava". Entre aproximadamente 1970 y 1990, los artículos y papers de Anant Agarwal, Alan Jay Smith, Mark D. Hill, Thomas R. Puzak y otros discutieron mejores diseños de caché de memoria. Los primeros modelos de caché de memoria se implementaron en ese momento, pero incluso mientras los investigadores investigaban y proponían mejores diseños, la necesidad de modelos de memoria más rápidos continuó. Esta necesidad se derivó del hecho de que aunque los primeros modelos de caché mejoraron la latencia de acceso a los datos, en términos de costo y limitaciones técnicas, no era factible que la caché de un sistema informático alcanzara el tamaño de la memoria principal. Desde 1990 en adelante, se propusieron ideas como agregar otro nivel de caché (segundo nivel), como respaldo para la caché de primer nivel. Jean-Loup Baer, Wen-Hann Wang, Andrew W. Wilson y otros han investigado este modelo. Cuando varios simulaciones e implementaciones demostraron los beneficios de los modelos de caché de dos niveles, el concepto de cachés de múltiples niveles se hizo popular como un nuevo y generalmente mejor modelo de cachés de memoria. Desde 2000, los modelos de caché de múltiples niveles han recibido una amplia atención y se implementan en muchos sistemas, como los cachés de tres niveles que se encuentran en los productos Core i7 de Intel.


Caché de múltiples niveles
El acceso a la memoria principal para cada ejecución de instrucción puede resultar en un procesamiento lento, con la velocidad del reloj dependiendo del tiempo necesario para encontrar y recuperar los datos. Para ocultar esta latencia de memoria al procesador, se utiliza la caché de datos. Siempre que el procesador necesite los datos, se recupera de la memoria principal y se almacena en la estructura de memoria más pequeña llamada caché. Si hay alguna necesidad adicional de esos datos, primero se busca en la caché antes de ir a la memoria principal. Esta estructura reside más cerca del procesador en términos del tiempo necesario para buscar y recuperar datos en comparación con la memoria principal. Los beneficios del uso de la caché se pueden demostrar mediante el cálculo del tiempo de acceso promedio (AAT) para la jerarquía de memoria con y sin caché.


= Tiempo de acceso promedio (AAT) =
Las cachés, siendo pequeñas en tamaño, pueden resultar en fallos frecuentes –cuando una búsqueda en la caché no proporciona la información buscada–, lo que resulta en una llamada a la memoria principal para recuperar los datos. Por lo tanto, el AAT se ve afectado por la tasa de fallo de cada estructura desde la que se busca los datos.




AAT
=
tiempo de acceso
+
(
(
tasa de fallo
)
×
(
penalización de fallo
)
)


{\displaystyle {\text{AAT}}={\text{tiempo de acceso}}+(({\text{tasa de fallo}})\times ({\text{penalización de fallo}}))}


El AAT para la memoria principal se da por el tiempo de acceso de la memoria principal. El AAT para las cachés puede darse por:

Tiempo de acceso caché + (Tasa de fallo caché × Penalización de fallo tiempo necesario para ir a la memoria principal después de fallar en la caché).
El tiempo de acceso de las cachés es menor que el tiempo de acceso de la memoria principal, por lo que el AAT para la recuperación de datos es significativamente menor cuando se accede a los datos a través de la caché en lugar de la memoria principal.


= Compromisos =
Aunque el uso de la caché puede mejorar la latencia de memoria, no siempre resulta en la mejora requerida para el tiempo necesario para recuperar los datos debido a la forma en que se organizan y navegan las cachés. Por ejemplo, las cachés mapeadas directamente que son del mismo tamaño suelen tener una tasa de fallo mayor que las cachés asociativas completas. Esto también puede depender del banco de pruebas del computador que esté probando el procesador y del patrón de instrucciones. Sin embargo, el uso de una caché asociativa completa puede resultar en un mayor consumo de energía, ya que debe buscar toda la caché cada vez. Debido a esto, el compromiso entre el consumo de energía (y el calor asociado) y el tamaño de la caché se convierte en crítico en el diseño de la caché.


= Evolución =

En el caso de un fallo de caché, el propósito de usar tal estructura se volverá inútil y el computador tendrá que ir a la memoria principal para recuperar los datos necesarios. Sin embargo, con una caché de múltiples niveles, si el computador falla en la caché más cercana al procesador (caché de nivel uno o L1), luego buscará en los siguientes niveles más cercanos de caché y solo recurrirá a la memoria principal si estos métodos fallan. La tendencia general es mantener la caché de nivel uno pequeña y a una distancia de 1-2 ciclos de reloj del procesador, con los niveles inferiores de caché aumentando en tamaño para almacenar más datos que el L1, por lo que están más distantes pero con una tasa de fallo menor. Esto resulta en un mejor AAT. El número de niveles de caché puede diseñarse por los arquitectos según sus requisitos después de verificar los compromisos entre el costo, los AAT y el tamaño.


= Ganancias en el rendimiento =

Con la escalabilidad tecnológica que permitió que los sistemas de memoria se accommodaran en un solo chip, la mayoría de los procesadores modernos tienen hasta tres o cuatro niveles de caché. La reducción en el AAT se puede entender mediante este ejemplo, donde el computador verifica el AAT para diferentes configuraciones hasta los cachés de nivel L3.
Ejemplo: memoria principal = 50 ns, L1 = 1 ns con una tasa de fallo del 10%, L2 = 5 ns con una tasa de fallo del 1%, L3 = 10 ns con una tasa de fallo del 0.2%.

Sin caché, AAT = 50 ns
Caché L1, AAT = 1 ns + (0.1 × 50 ns) = 6 ns
Caché L1-L2, AAT = 1 ns + (0.1 × [5 ns + (0.01 × 50 ns)]) = 1.55 ns
Caché L1-L3, AAT = 1 ns + (0.1 × [5 ns + (0.01 × [10 ns + (0.002 × 50 ns)])]) = 1.5101 ns


= Desventajas =
La memoria caché tiene un costo marginal mayor que la memoria principal y, por lo tanto, puede aumentar el costo del sistema en general.
Los datos almacenados en caché se mantienen solo mientras se proporciona energía a la caché.
Se requiere un mayor espacio en el chip para el sistema de memoria.
Los beneficios pueden minimizarse o eliminarse en el caso de programas grandes con una mala localidad temporal, que acceden con frecuencia a la memoria principal.


Propiedades


= Bancada versus unificada =
En una caché bancada, la caché se divide en una caché dedicada al almacenamiento de instrucciones y otra dedicada al almacenamiento de datos. Por el contrario, una caché unificada contiene tanto instrucciones como datos en la misma caché. Durante un proceso, la caché de nivel uno (o el nivel superior más alto en relación con su conexión al procesador) se accede por el procesador para recuperar tanto instrucciones como datos. La necesidad de que ambas acciones se implementen al mismo tiempo requiere múltiples puertos y más tiempo de acceso en una caché unificada. Tener múltiples puertos requiere más hardware y cables, lo que lleva a una estructura significativa entre las cachés y las unidades de procesamiento. Para evitar esto, la caché de nivel uno a menudo se organiza como una caché bancada, lo que resulta en menos puertos, menos hardware y, en general, menos tiempo de acceso.
Los procesadores modernos tienen cachés divididas, y en sistemas con cachés de múltiples niveles, los niveles inferiores pueden ser unificados mientras que los niveles superiores pueden ser divididos.


= Políticas de inclusión =

Si un bloque presente en la capa superior de la caché también puede estar presente en la capa inferior de la caché es regido por la política de inclusión de la memoria del sistema, que puede ser inclusiva, exclusiva o no inclusiva no exclusiva (NINE).
Con una política inclusiva, todos los bloques presentes en la capa superior de la caché también tienen que estar presentes en la capa inferior de la caché. Cada componente de la caché superior es un subconjunto del componente de la caché inferior. En este caso, dado que hay una duplicación de bloques, hay un desperdicio de memoria. Sin embargo, la verificación es más rápida.
Bajo una política exclusiva, todos los componentes de la jerarquía de la caché son completamente exclusivos, por lo que ningún elemento en la capa superior de la caché estará presente en ninguno de los componentes de la caché inferior. Esto permite un uso completo de la memoria caché. Sin embargo, hay una alta latencia de acceso a la memoria.
Las políticas anteriores requieren un conjunto de reglas para implementarlas. Si ninguna de estas se impone, la política de inclusión resultante se denomina no inclusiva no exclusiva (NINE). Esto significa que la caché superior puede o no estar presente en la caché inferior.


= Políticas de escritura =
Hay dos políticas que definen la forma en que se actualizará un bloque modificado de la caché en la memoria principal: escritura a través y escritura de vuelta.
En el caso de la política de escritura a través, cada vez que cambia el valor del bloque de la caché, se modifica también en la jerarquía de memoria inferior. Esta política asegura que los datos se almacenen de manera segura a medida que se escriben a lo largo de la jerarquía.
Sin embargo, en el caso de la política de escritura de vuelta, el bloque modificado de la caché se actualizará en la jerarquía inferior solo cuando se expulse el bloque de la caché. Se adjunta un "bit sucio" a cada bloque de la caché y se establece cada vez que se modifica el bloque de la caché. Durante la expulsión, los bloques con el bit sucio configurado se escribirán en la jerarquía inferior. Bajo esta política, hay un riesgo de pérdida de datos, ya que la copia más reciente del dato solo se almacena en la caché y, por lo tanto, se deben observar algunas técnicas correctivas.
En caso de una escritura donde el byte no esté presente en el bloque de la caché, el byte puede traerse a la caché según se determine por una política de escritura con asignación o sin asignación. La política de escritura con asignación establece que en caso de un fallo de escritura, el bloque se recupera de la memoria principal y se coloca en la caché antes de escribir. En la política de escritura sin asignación, si el bloque se pierde en la caché, se escribirá en la jerarquía inferior sin recuperar el bloque en la caché.
Las combinaciones comunes de las políticas son "escribir de vuelta, escribir con asignación" y "escribir a través, escribir sin asignación".


= Compartida versus privada =

Una caché privada se asigna a un núcleo particular en un procesador y no puede ser accedida por otros núcleos. En algunas arquitecturas, cada núcleo tiene su propia caché privada; esto crea el riesgo de bloques duplicados en la arquitectura de caché del sistema, lo que resulta en una menor utilización de capacidad. Sin embargo, este tipo de elección de diseño en una arquitectura de caché de múltiples niveles puede ser bueno para una menor latencia de acceso a los datos.
Una caché compartida es una caché que puede ser accedida por múltiples núcleos. Dado que es compartida, cada bloque en la caché es único y, por lo tanto, tiene una mayor tasa de acierto, ya que no habrá bloques duplicados. Sin embargo, la latencia de acceso a los datos puede aumentar ya que múltiples núcleos intentan acceder a la misma caché.
En procesadores multicore, la elección de diseño de hacer una caché compartida o privada afecta el rendimiento del procesador. En la práctica, la caché de nivel uno L1 (o a veces L2) se implementa como privada y las cachés de niveles inferiores se implementan como compartidas. Este diseño proporciona altas tasas de acceso para las cachés de alto nivel y bajas tasas de fallo para las cachés de nivel inferior.


Modelos de implementación recientes


= Intel Xeon Emerald Rapids (2024) =
Hasta 64 núcleos:

Caché L1 – 80 KB por núcleo
Caché L2 – 2 MB por núcleo
Caché L3 – 5 MB por núcleo (es decir, hasta 320 MB en total)


= Intel i5 Raptor Lake-HX (2024) =
6 núcleos (rendimiento | eficiencia):

Caché L1 – 128 KB por núcleo
Caché L2 – 2 MB por núcleo | 4–8 MB semi-compartida
Caché L3 – 20–24 MB compartida


= AMD EPYC 9684X (2023) =
96 núcleos:

Caché L1 – 64 KB por núcleo
Caché L2 – 1 MB por núcleo
Caché L3 – 1152 MB compartida


= Apple M1 Ultra (2022) =
20 núcleos (4:1 "rendimiento" | "eficiencia" núcleo):

Caché L1 – 320|192 KB por núcleo
Caché L2 – 52 MB semi-compartida
Caché L3 – 96 MB compartida


= AMD Ryzen 7000 (2022) =
6 a 16 núcleos:

Caché L1 – 64 KB por núcleo
Caché L2 – 1 MB por núcleo
Caché L3 – 32 a 128 MB compartida


= AMD Zen 2 microarquitectura (2019) =
Caché L1 – 32 KB de datos y 32 KB de instrucciones por núcleo, 8 vías
Caché L2 – 512 KB por núcleo, 8 vías inclusiva
Caché L3 – 16 MB local por 4 núcleos CCX, 2 CCXs por chiplet, 16 vías no inclusiva. Hasta 64 MB en CPUs de escritorio y 256 MB en CPUs de servidor


= AMD Zen microarquitectura (2017) =
Caché L1 – 32 KB de datos y 64 KB de instrucciones por núcleo, 4 vías
Caché L2 – 512 KB por núcleo, 4 vías inclusiva
Caché L3 – 4 MB local y remota por 4 núcleos CCX, 2 CCXs por chiplet, 16 vías no inclusiva. Hasta 16 MB en CPUs de escritorio y 64 MB en CPUs de servidor


= Intel Kaby Lake microarquitectura (2016) =
Caché L1 (instrucciones y datos) – 64 KB por núcleo
Caché L2 – 256 KB por núcleo
Caché L3 – 2 MB a 8 MB compartida


= Intel Broadwell microarquitectura (2014) =
Caché L1 (instrucciones y datos) – 64 KB por núcleo
Caché L2 – 256 KB por núcleo
Caché L3 – 2 MB a 6 MB compartida
Caché L4 – 128 MB de eDRAM (solo en modelos Iris