Diferencias entre la caché L1, L2, L3 y su importancia en la CPU

Cada CPU moderna tiene varios niveles de memoria caché. Ya sea on-chip o también on-package en algunos casos. Sea como sea, esta memoria intermedia tiene una gran repercusión en el rendimiento del sistema. Gracias a ella se pueden obtener datos e instrucciones para ser procesadas de una forma más rápida.

No todos los niveles de memoria son exactamente iguales. Cada uno tiene unas características diferentes que deberías conocer.

Introducción

Desde los primitivos computadores que usaban tarjetas perforadas para cargar los programas y datos, hasta el actual multinivel de memoria, pasando por la llegada de las primeras memorias magnéticas, mucho han  evolucionado estos sistemas.

Actualmente, las modernas arquitecturas tienen varios niveles que se podrían representar en forma de pirámide:

  • En la base estarían las memorias secundarias (p.e.: algún tipo de ROM, magnéticas, flash), que son las más grandes en capacidad, pero también las más lentas. Además, son persistentes, no se borran cuando se corta el suministro de energía. Un ejemplo de este tipo de memorias serían los discos duros.
  • Como éstos no eran suficientemente rápidos para satisfacer la demanda de los microprocesadores, se implementó un nivel intermedio: la memoria principal. Es decir, la RAM. Ésta memoria es de menor capacidad que la secundaria, pero bastante más rápida, al ser tipo DRAM (Dynamic RAM), pero volátil.
  • A medida que los microprocesadores avanzaban, ni ésta memoria principal era lo suficientemente rápida como para evitar los cuellos de botella. Por eso se comenzaron a agregar módulos de otra memoria más rápida entre la RAM y la CPU y que se llama caché. Estos módulos luego fueron implementados más cerca del microprocesador y con mayor velocidad (en el propio empaquetado de la CPU, es decir, on-package). Con los avances en microelectrónica, esta caché pasó a ser aún más rápida e integrarse dentro del propio chip de la CPU (on-chip), y con varios niveles. Pero todas ellas de tipo SRAM (Static RAM).
  • Aunque la memoria caché es muy rápida, y está cera de la CPU para satisfacer la demanda de datos e instrucciones de forma más rápida, existe otra memoria aún más rápida en la pirámide, y estaría en la cúspide. Esos son los registros. Estos pueden almacenar tan solo uno bits, pero son muy rápidos. Además, hay varios cerca de las unidades funcionales para alimentarlas de forma rápida (PC, estado, acumulador, de propósito general, etc.).

Como ves, desde la base (memoria secundaria), hasta la cúspide (registros), cada vez se aumenta más la velocidad, pero se reduce la capacidad. Esto se debe a que las memorias más próximas a la base son más baratas de implementar, mientras las más rápidas y próximas a la cúspide son mucho más caras, y por eso no es rentable que tengan tamaños elevados.

DRAM vs SRAM

La memoria principal se implementa mediante algún tipo de DRAM. Eso implica que las celdas de memoria se tengan que actualizar constantemente, mediante una señal (refresh). De lo contrario, se perderían los datos si no se refrescan durante periodos largos. Esa característica hace que consuman más energía y que sean más lentas que una SRAM.

La SRAM es mucho más eficiente energéticamente, y no necesita actualizarse, por lo que es bastante más rápida. En cambio, implementar cada celda es mucho más caro, lo que impide su generalización y que no sea rentable implementar capacidades muy elevadas.

Si se analizan a nivel electrónico, se puede entender la diferencia de velocidades entre ambas. Las DRAM usan una mezcla de condensadores y transistores para implementar cada celda de memoria. En cambio, la SRAM usa solo 6 transistores.

Diferencias entre niveles de caché

Dentro de la caché, se han ido separando en niveles diferentes. Cada uno de esos niveles es ligeramente diferente. Aunque todos compartan la misma tecnología SRAM, sus esquemas y capacidades, e incluso el propósito, es diferente:

  • LLC (Last Level Cache): es el nivel más alto de la memoria caché en un sistema. Dependiendo del sistema puede ser una L3, una L2, e incuso una L4 en algunos casos. Este último nivel está unificado, es decir, guarda tanto datos como instrucciones indiferentemente. También es el de mayor tamaño, y suele estar compartido por los diferentes núcleos. En algunos casos se puede implementar dentro del propio chip, aunque ha habido casos en los que se ha implementado fuera de él (off-chip).
  • L2: en los modernos microprocesadores se encuentra on-chip, trabajando a la misma frecuencia que el propio microprocesador. Antes, en algunos diseños se encontraba fuera y trabajaba a la misma frecuencia que el bus de datos de la placa base. En este caso también está unificada.
  • L1: es la de más bajo nivel, y actualmente se encuentra dividida en dos bloques. Uno es la L1 para instrucciones, y otro es la L1 para datos. Es decir, hay una L1 específica que solo almacena instrucciones, y una L1 solo para datos. En este caso también está dentro del chip de la CPU y trabajando a la misma frecuencia que la CPU.

Aunque ahora la mayoría de sistemas tienen la misma frecuencia que la CPU, es decir, CPU = L3 = L2 = L1, no siempre ha sido así, y no tiene por qué serlo en casos particulares. Lo que sí tienes que saber es que la latencia (tiempo que se tarta en acceder para leer/escribir) no será igual en ningún caso. En ese caso se tiene que L1 L< L2 < L3 < L4, es decir, se tarda menos tiempo en acceder a una L1 que a una L2, y así sucesivamente.

Caché inclusiva vs exclusive

Cuando una CPU solicita información, primero buscará en la L1, que es lo más rápido. Si se encuentra allí lo podrá obtener para procesarlo. En cambio, si se produce un fallo (no se encuentra), pasará a buscarlo en la L2, y así sucesivamente en todos los niveles. Eso sería mucho menos costoso en tiempo (número de ciclos de reloj) que irlo a buscar a la memoria RAM.

Cuando una información solicitada no se encuentra en ningún nivel de caché y se tiene que traer desde la RAM, entonces se almacenará en varios niveles de caché para que la próxima vez que se solicite se pueda acceder más rápido a él. En cambio, no siempre es tan sencillo, ya que estas memorias no son infinitas y se necesita ir desocupando bloques para almacenar nueva información, por lo que no siempre que se trae desde la RAM estará ya en caché.

Además, cuando un valor está en varios niveles de caché, si por algún motivo se llenase la L2 y se tuviera que eliminar un valor para dejar hueco, se enviaría una señal a la L1 para que eliminase ese mismo valor. Esto es lo que se conoce como caché inclusiva, que difiere de la exclusiva.

En la exclusiva no enviaría esa señal al otro nivel para que invalide el valor. En este caso, si el valor buscado por la CPU no está en la L1, se pasa a la L2, y así sucesivamente. En caso de estar en la L2, se pasará a la L1. Pero si no está presente en ningún nivel, se busca en RAM, al igual que en la inclusiva, solo que en este caso solo se almacenará en la L1, y no se copia por igual en el resto de niveles.

Existe otro tipo de caché llamado NINE (No inclusive, No exclusive), una especie de hibridación de ambas. No es tan popular como los anterior, pero en este caso no se incluyen ni excluyen los bloques en los niveles. En este caso, la CPU busca primero en L1, si se encuentra, usará el valor. Si no, buscará en L2 (si está, se pasa a L1 y se usa), y así sucesivamente. Pero, si no se encontrase en ningún nivel, entonces se busca en la RAM, como en los otros casos, pero se colocaría en los diferentes niveles, como en la inclusiva, pero sin invalidación de bloques como en la exclusiva.

¿Cuánto se gana en rendimiento?

Así es como esta memoria caché mejora el rendimiento. Imagina la cantidad de ciclos de reloj que ahorra a la CPU al no tener que ir siempre a buscar el valor a la RAM.

Para poner detalles más representativos de lo que se puede ganar, aquí te dejo un ejemplo de las latencias de un Intel Xeon 5500 Series cuando tiene que acceder a los distintos niveles (aproximado):

  • L1 = 4 ciclos de reloj (1.2ns)
  • L2 = 10 ciclos de reloj (3ns)
  • L3 = 40-75 ciclos de reloj (12-22.5ns)
  • RAM = 60 ns

No siempre se tarda la misma cantidad de ciclos en acceder, eso dependerá de la microarquitectura de la CPU. Además, incluso si las cachés fueran idénticas y la microarquitectura también, la frecuencia también influye. Ya sabes que el periodo que dura un ciclo está relacionado con la (f=1/T). Por tanto, en un chip a 1Ghz el ciclo dura 1 ns, mientras que en uno de 3Ghz será de unos 333 ps (0,333 ns).

Como ves, cuando se encuentra el dato en la L1 se tardaría solo 1.2 nanosegundos en acceder a él, mientras que en la RAM son 60 ns, es decir, 50 veces más rápido que la RAM. Eso es un impacto de rendimiento enorme. ¿Te imaginas qué sería de tu CPU sin caché?

Otras características

Además de inclusiva y exclusiva, también hay otras características que diferencian a las implementaciones de caché que tienen los microprocesadores. De hecho, se pueden tener un nivel de un tipo y otro nivel de otro tipo. Me estoy refiriendo a aspectos como:

  • Política de ubicación: pueden ser directa, asociativa, o asociativa por conjuntos. La más simple de implementar es la directa, aunque también es la peor en cuanto a rendimiento. Estas políticas solo describen la forma de ubicar los bloques de información dentro de la caché. Las más populares suelen ser las asociativas, y dentro de estas puedes encontrar varios tipos según su n-way (2-way, 4-way…).
  • Política de extracción: pueden ser por demanda (se trae el valor cuando ha sido referenciado y no se encuentra en el nivel), y prebúsqueda o prefetch (se trae el bloque i referenciado, y además el i+1, que muy probablemente se necesitará también más tarde).
  • Política de reemplazo: el reemplazo de bloques cuando se llena se puede hacer de forma aleatoria, FIFO (primero en entrar, primero en salir), LRU (el menos usado recientemente), o LFU (usado con menos frecuencia).
  • Política de actualización: pueden ser con escritura inmediata o directa (write-through) o escritura diferida (write-back). En el primer caso se simplifica el diseño del sistema, y siempre se mantendrá una copia de la línea de caché en la memoria principal. Con la segunda, en ocasiones se encontrarán los datos en la memoria principal y a veces en la memoria caché. En este segundo caso, cuando se encuentra en la caché, la CPU evitará que la RAM responda enviando información, ya que podría tener un valor obsoleto. Y eso significa un sistema electrónico más complejo que en la inmediata.

Por ejemplo, el subsistema de memoria de la microarquitectura AMD Zen 2 usa una caché L1 4-way asociativa.