Estudio de la memoria cache: Definición, su evolución hasta la actualidad, diseño, caracterización y utilidad en arquitecturas antiguas y modernas

FACULTAD DE CIENCIAS MATEMATICAS Y FÍSICAS

Autores:

EDUARDO CHAVEZ 
 RICARDO CHOEZ
 EDWIN SALAZAR 
 RONNY HIDALGO

Introducción 

 
En el mundo de la informática, la memoria caché es una tecnología clave que mejora significativamente el rendimiento del procesamiento de datos en computadoras y otros dispositivos electrónicos. Esta memoria especializada actúa como un intermediario entre la unidad central de procesamiento (CPU) y la memoria principal del sistema (RAM), permitiendo una recuperación más rápida de datos y programas utilizados con frecuencia.

La necesidad de la memoria caché surge de la disparidad en velocidades de acceso entre diferentes tipos de memoria en un sistema informático. Mientras que la CPU es extremadamente rápida en la ejecución de instrucciones, la RAM, aunque también rápida, es significativamente más lenta que la CPU. Esta discrepancia en velocidades puede llevar a un cuello de botella en el rendimiento, ya que la CPU debe esperar a que los datos se carguen desde la memoria principal, lo que resulta en una disminución del rendimiento general del sistema. 



Definición de la memoria cache

 

La memoria caché es una solución efectiva para reducir la brecha entre la velocidad del procesador y la memoria principal (RAM). Al estar ubicada dentro del procesador, es decir, en la CPU misma, permite que el acceso a la información sea extremadamente rápido. Su propósito principal es almacenar copias de datos y/o instrucciones que son utilizados con frecuencia por el procesador, de manera que cuando se ne cesiten nuevamente, puedan ser accedidos rápidamente sin tener que recurrir a la memoria RAM.

La ventaja clave de la memoria caché es su alta velocidad de acceso. A diferencia de la RAM, que funciona a velocidades mucho más bajas, la caché ofrece tiempos de latencia significativamente reducidos. Al tener una capacidad mucho menor en comparación con la RAM, es importante que la caché esté optimizada para almacenar datos esenciales para el rendimiento del sistema, lo que se logra mediante algoritmos inteligentes que gestionan qué datos se almacenan y cuáles se eliminan. (profesionalreview)

 

El funcionamiento eficiente de la memoria caché se basa en el principio de localidad, que se refiere a la tendencia del procesador a acceder a datos e instrucciones cercanas a los que se han accedido recientemente. La memoria caché explota esta propiedad al almacenar datos que probablemente se necesitarán nuevamente pronto. Si un dato o instrucción solicitada no se encuentra en la caché, se produce una "falta de caché" (cache miss), y el sistema buscará ese dato en la memoria RAM, lo copiará en la caché y, si es posible, también traerá datos adicionales cercanos (también conocido como "carga anticipada" o prefetching) para optimizar futuros accesos.

En resumen, la memoria caché es una solución esencial para acelerar el rendimiento de las CPU y reducir los tiempos de espera del procesador mientras accede a los datos. Su diseño y optimización inteligentes permiten que los sistemas informáticos funcionen de manera más eficiente al aprovechar la proximidad física y la rápida velocidad de acceso que ofrece esta pequeña pero poderosa memoria dentro del procesador.

Evolución De La Memoria Cache

A repasar fondo los elementos más importantes que dan vida a un procesador. Entre ellos se encuentra la memoria caché, un componente que ha vivido una importante evolución durante las últimas décadas pero que todavía hoy sigue siendo un gran desconocido.

Actualmente podemos diferenciar la memoria caché en L1, L2 y L3, nomenclaturas con las que se identifican los distintos niveles en los que se encuadran. También se utiliza, aunque con poca frecuencia, un tipo de memoria caché conocida como L4, sobre todo en procesadores que vienen con GPUs integradas.

A continuación, te presento las principales etapas de su evolución:

 



Caché nivel 1 (L1):  A fines de la década de 1970 y principios de la de 1980, se introdujeron las primeras cachés de nivel 1, es el nivel más básico, la más cercana al procesador y la más rápida. También es la que menos capacidad tiene, por ejemplo, un procesador de dos núcleos como el Pentium G4560 tiene 64 KB en total (32 KB por núcleo), aunque los modelos más potentes (serie Xeon y Epyc) pueden alcanzar los 3 MB sin problema.

Caché nivel 2 (L2): En la década de 1990, se agregó una caché de nivel 2 externa al procesador, es un nivel intermedio que presenta un buen equilibrio entre capacidad, cercanía y velocidad. Siguiendo el ejemplo anterior el Pentium G4560 tiene 512 KB (256 KB por núcleo) de caché L2, pero un Threadripper 2990WX llega a los 16 MB en total (512 KB por núcleo).

Caché nivel 3 (L3): A medida que los procesadores se volvieron más complejos y la demanda de rendimiento aumentó, se agregó una caché de nivel 3 en algunos sistemas a principios del siglo XXI, posiciona en un nivel inferior a la anterior tanto en cercanía como en velocidad, pero tiene una capacidad mucho mayor. 

Por ejemplo: el Pentium G4560 tiene 3 MB de caché L3 compartida en sus dos núcleos, mientras que el Threadripper 2990WX viene con un total de 64 MB (16 MB compartidos por cada bloque de ocho núcleos).

Caché L4: es un tipo de memoria caché poco habitual que se utiliza normalmente como apoyo para mejorar el rendimiento de GPUs integradas. Por ejemplo, el Core i5 5775C venía con 6 MB de caché L3 y 128 MB de eDRAM como caché L4, que se utilizaba como buffer para la gráfica Intel Iris Pro 6200 que integraba. Así se mejoraba el ancho de banda y se reducía el impacto de tener que recurrir a la RAM como memoria gráfica.

Cuando un procesador busca instrucciones y datos que necesita primero recurre a la memoria caché L1, si no encuentra nada recurre a la caché L2 y finalmente a la caché L3. En caso de que ninguna de las cachés contenga lo que está buscando no tiene más opción que recurrir a la memoria RAM, y si tampoco está en ella tiene que realizar un ciclo de trabajo completo, con todo lo que ello supone a nivel de rendimiento.

Bien, para acceder a cada nivel de memoria caché es necesario un tiempo determinado, un retraso que se conoce como latencia, y que representa ese retardo que tiene que asumir el sistema hasta que el procesador encuentre lo que necesita para trabajar. La latencia de acceso a la caché L1 es la más baja, y se incrementa de forma considerable en los niveles L2 y L3, hasta tocar techo en el caso de tener que acceder a la memoria RAM. (Ros, 2019). 

Elementos del diseño de la memoria Caché

De acuerdo con William Stallings(2005) existen 6 elementos fundamentales al momento de diseñar una memoria cache. Estas son:Tamaño de caché

  •  Función de correspondencia
  • Algoritmo de sustitución
  •  Política de escritura 
  •  Tamaño de línea
  •   Números de cachés  

Tamaño de caché

Es esencial que el tamaño del cache fuera lo suficientemente pequeño como para que el coste total medio por bit se aproxime al de la memoria principal sola, y que fuera lo suficientemente grande como para que el tiempo de acceso medio total sea próximo al de la caché sola. Hay otras muchas motivaciones para minimizar el tamaño de la caché. Cuanto más grande es, mayor es el número de puertas implicadas en direccionar la caché. El resultado es que cachés grandes tienden a ser ligeramente más lentas que las pequeñas. El tamaño de caché está también limitado por las superficies disponibles de chip y de tarjeta. Como las prestaciones de la caché son muy sensibles al tipo de tarea, es imposible predecir un tamaño óptimo.

Función de correspondencia

La elección de la función de correspondencia determina cómo se organiza la caché. Pueden utilizarse tres técnicas: directa, asociativa, y asociativa por conjuntos. 

 

Correspondencia directa: consiste en hacer corresponder cada bloque de memoria principal a solo una línea posible de caché. La función de correspondencia se implementa fácilmente utilizando la dirección. Desde el punto de vista del acceso a caché, cada dirección de memoria principal puede verse como dividida en tres campos Los w bits menos significativos identifican cada palabra dentro de un bloque de memoria principal; Los s bits restantes especifican uno de los 2S bloques de la memoria principal. y un campo de línea de r bits. Este último campo identifica una de las m = 2r líneas de la caché.

Correspondencia asociativa: La correspondencia asociativa supera la desventaja de la directa, permitiendo que cada bloque de memoria principal pueda cargarse en cualquier línea de la caché. En este caso, la lógica de control de la caché interpreta una dirección de memoria simplemente como una etiqueta y un campo de palabra. El campo de etiqueta identifica unívocamente un bloque de memoria principal. Para determinar si un bloque está en la caché, su lógica de control debe examinar simultáneamente todas las etiquetas de líneas para buscar una coincidencia.

Correspondencia asociativa por conjuntos: Es una técnica utilizada en el diseño de memorias caché para organizar y mapear bloques de datos en la caché. En un sistema de correspondencia asociativa por conjuntos, cuando un bloque de datos se necesita para ser almacenado en la caché, se realiza una búsqueda en un conjunto específico para determinar si el bloque ya está presente en alguna de las líneas de ese conjunto. Si el bloque se encuentra en alguna línea de ese conjunto (es decir, se produce un acierto o hit), entonces se accede directamente a esa línea de caché para recuperar el dato solicitado. Si el bloque no se encuentra en ninguna de las líneas del conjunto (es decir, se produce una falta o miss), entonces se debe reemplazar una de las líneas con el bloque deseado.

Algoritmo de Sustitución

Son mecanismos utilizados para determinar qué bloque de datos se eliminará de la caché cuando sea necesario reemplazarlo por otro. Estos algoritmos son esenciales para garantizar la coherencia entre la caché y la memoria principal y para maximizar el rendimiento del sistema, al tratar de minimizar los fallos de caché (misses) y maximizar los aciertos de caché (hits).

Algunos de los algoritmos de sustitución más comunes en la memoria caché son:

LRU (Least-Recently Used): Este algoritmo reemplaza el bloque que no ha sido accedido durante el período más largo. Es decir, el bloque que ha estado inactivo o sin ser utilizado durante más tiempo es el candidato para ser reemplazado. LRU tiende a ofrecer un buen rendimiento en situaciones donde hay alta localidad temporal en los accesos a la memoria.

FIFO (First In, First Out): Se sustituye aquel bloque del conjunto que ha estado más tiempo en la caché. El algoritmo FIFO puede implementarse fácilmente mediante una técnica cíclica (round-robin) o buffer circular.

LFU (Least Frecuently Used): Se sustituye aquel bloque del conjunto que ha experimentado menos referencias. LFU podría implementarse asociando un contador a cada línea. 

Aleatorio: En este enfoque, se elige un bloque de forma aleatoria para ser reemplazado. Es decir, el bloque a ser reemplazado se selecciona al azar. Este algoritmo es simple, pero puede no ser el más eficiente en términos de rendimiento. 

Política de escritura

Se refiere a la estrategia utilizada para decidir cuándo y cómo actualizar los datos en la caché y, en consecuencia, en la memoria principal (RAM) después de que los datos hayan sido modificados en la caché.

Existen dos políticas principales de escritura en la memoria caché:

Escritura inmediata: Utilizando esta técnica, todas las operaciones de escritura se hacen tanto en caché como en memoria principal, asegurando que el contenido de la memoria principal siempre es válido. Cualquier otro módulo procesador-caché puede monitorizar el tráfico a memoria principal para mantener la coherencia en su propia caché. La principal desventaja de esta técnica es que genera un tráfico sustancial con la memoria que puede originar un cuello de botella.

Escritura por retraso: En esta política, cuando se modifica un bloque de datos en la caché, la actualización se realiza solo en la caché y no en la memoria principal de inmediato. En su lugar, los datos modificados se marcan como sucios y la escritura en la memoria principal se pospone hasta que el bloque sea reemplazado en la caché.

 

Tamaño de Línea

Cuando se recupera y ubica en caché un bloque de datos, se recuperan no sólo la palabra deseada sino además algunas palabras adyacentes. A medida que aumenta el tamaño de bloque, la tasa de aciertos primero aumenta debido al principio de localidad, el cual establece que es probable que los datos en la vecindad de una palabra referenciada sean referenciados en un futuro próximo. Al aumentar el tamaño de bloque, más datos útiles son llevados a la caché. Sin embargo, la tasa de aciertos comenzará a decrecer cuando el tamaño de bloque se haga aún mayor y la probabilidad de utilizar la nueva información captada se haga menor que la de reutilizar la información que tiene que reemplazarse.

Números de caché

Cuando se introdujeron originalmente las cachés, un sistema tenía normalmente solo una caché. Más recientemente, se ha convertido en una norma el uso de múltiples cachés. Hay dos aspectos de diseño relacionados con este tema que son el número de niveles de caché, y el uso de caché unificada frente al de cachés separadas.

Cachés multinivel: Las caches multinivel, también conocidas como jerarquías de caché, son una técnica avanzada de diseño de memoria caché que utiliza múltiples niveles de caché en un sistema informático. Estos niveles de caché están organizados en una jerarquía con el objetivo de mejorar el rendimiento del sistema y reducir la latencia de acceso a los datos más frecuentemente utilizados por la CPU.

Caché unificado frente a cachés separadas: Cuando hicieron su aparición las cachés onchip, muchos de los diseños contengan una sola caché para almacenar las referencias tanto a datos como a instrucciones. Más recientemente, se ha hecho normal separar la caché en dos: una dedicada a instrucciones y otra a datos.

Una caché unificada tiene varias ventajas potenciales:

                  Para un tamaño dado de caché, una unificada tiene una tasa de aciertos mayor que una caché partida, ya que nivela automáticamente la carga entre captación de instrucciones y de datos. Es decir, si un patrón de ejecución implica muchas más captaciones de instrucciones que de datos, la caché tenderá a llenarse con instrucciones, y si el patrón de ejecución involucra relativamente más captaciones de datos, ocurrirá lo contrario. 

                  Solo se necesita diseñar e implementar una caché.

Caracterización y funcionamiento de la memoria caché 

La memoria caché es una memoria de acceso rápido situada entre la CPU y la memoria principal, cuyo propósito es reducir los tiempos de acceso a datos e instrucciones para mejorar el rendimiento del procesador. Almacena copias de datos utilizados recientemente (localidad temporal) y bloques de datos contiguos (localidad espacial), permitiendo a la CPU acceder rápidamente a la información sin esperar a que se recupere de la memoria RAM. Esto proporciona una ganancia significativa de tiempo al reducir los ciclos de espera de la CPU para acceder a la información. La memoria caché es esencial para mejorar el rendimiento de los sistemas informáticos y es gestionada automáticamente por el hardware. Existe otra memoria de acceso rápido llamada "memoria Scratchpad", que se ubica cerca del procesador, pero requiere una gestión manual por parte del programa. (Pérez, 2019)

 

Una memoria caché no incluye en su definición cómo debe ser implementada. Se puede utilizar una pequeña memoria como caché de la memoria principal DRAM, pero una DRAM más rápida puede actuar como caché de una DRAM más lenta. De hecho, la propia motivación de este trabajo es determinar las mejores formas de utilizar una SDRAM (Synchronous Dynamic Random Access Memory) como caché de una RRAM (Resistive Random Access Memory). Ambas serán detalladas más adelante. El objetivo principal de una caché es predecir el comportamiento futuro de la aplicación, para reducir la carga de las operaciones sobre niveles inferiores en la jerarquía de memoria. (Pérez, 2019)


Es decir, que las palabras próximas en memoria tienden a ser referenciadas juntas en el tiempo. La localidad espacial viene motivada fundamentalmente por la linealidad de los programas (secuencia miento lineal de las instrucciones) y el acceso a las estructuras de datos regulares.

El funcionamiento de la memoria caché se puede resumir en el diagrama de flujo de la siguiente figura. 

En él se describe el proceso de traducción de la dirección física procedente de la CPU (en el supuesto que el procesador no disponga de memoria virtual o esté desactivado) en el dato ubicado en la posición de memoria determinada por dicha dirección: 


Niveles de la memoria caché

Anteriormente un microprocesador tenía dos niveles de memoria caché, memoria caché L1 y memoria caché L2. La memoria caché L1, está incorporada en el núcleo del procesador, que suele ser de 8, 16, 32, 64 o 128 Kbyte, que funciona a la misma frecuencia de reloj que el resto de la CPU. Por lo tanto, la memoria caché L1 forma parte del procesador. Se puede dividir en dos secciones: memoria caché L1 para datos y memoria caché L1 para instrucciones. La memoria caché L2 es de mayor capacidad que la caché L1, pero es más lenta que la caché L1, en los últimos microprocesadores viene integrado un tercer nivel denominado caché L3, que es de mayor capacidad que L2, pero son más lentas que ésta. (Velásquez, 2018)


 

Funcionamiento de la jerarquía de memoria

Cuando la memoria caché contiene un dato o instrucción que la CPU está buscando, se dice que se produce un acierto (hit), mientras que si no lo contiene se produce un fallo (miss). Según el hit rate y miss rate de un sistema, se tendrá mayor o menor rendimiento. Ten en cuenta que si la capacidad de la caché es mayor, hay más posibilidades de que una información buscada esté y no haya sido borrada para almacenar otra información diferente. Aunque esto no solo depende del tamaño de la caché, también de las políticas y algoritmos empleados, etc. (Ortega, 2020)

En un sistema con una CPU que tiene 3 niveles de caché, la búsqueda de instrucciones y datos para ejecutarlos puede seguir el siguiente proceso:

1.     L1d y L1i: La CPU busca primero en el nivel L1 de datos (L1d) y el nivel L1 de instrucciones (L1i). Si la información se encuentra en alguno de estos niveles, se produce un "hit" y se obtiene rápidamente la instrucción y el dato para su ejecución. Si no se encuentra en ninguno de los L1, se produce un "fallo" o "miss".

2.     L2: Ante un fallo en los niveles L1, la CPU busca en el nivel L2, que es una memoria caché más grande y unificada. Si la información está presente en el L2, se produce un "hit" y se obtiene para su ejecución. Si no se encuentra, se produce un fallo en el L2 y se pasa al siguiente nivel.

3.     L3 (LLC): Si se produce un fallo en el L2, la CPU busca en el nivel L3 (Last Level Cache), que es una caché de mayor capacidad. Si la información se encuentra en el L3, se produce un "hit" y se obtiene para su ejecución. Si no se encuentra, se produce un fallo en el L3.

4.     Memoria principal o RAM & E/S: Ante un fallo en el L3, la CPU busca en la memoria principal o RAM. Este acceso lleva más ciclos debido a la mayor latencia. Es probable que

la información esté presente en la RAM. Sin embargo, puede darse el caso de que no se encuentre allí.

5.     Memoria secundaria (SWAP o memoria virtual): Si la información buscada no está en la RAM, el sistema operativo (S.O.) debe llevar a cabo un proceso para pasar el dato e instrucción desde la memoria de intercambio o memoria virtual hasta la RAM. Este paso implica un mayor número de ciclos de espera y se busca evitar en la medida de lo posible.

(Ortega, 2020)


Utilidad en arquitecturas antiguas y modernas 

La memoria caché fue desarrollada como una solución para mejorar el rendimiento de los procesadores cuando las memorias principales no podían mantenerse al ritmo de velocidad de estos últimos. En el pasado, como en la época del procesador 386 en 1991, la velocidad de las memorias RAM ya era un factor limitante para el rendimiento del sistema. Este problema se ha acentuado aún más en la actualidad, dado el alto rendimiento de los procesadores modernos. (Gárcia, 2021)

Para resolver esta limitación, se introdujo la memoria caché, una memoria de acceso ultrarrápido diseñada para almacenar los datos más frecuentemente utilizados por el procesador. La memoria caché actúa como un intermediario entre el procesador y la memoria RAM, almacenando copias de datos e instrucciones que se utilizan con mayor frecuencia. De esta manera, el procesador puede acceder a los datos en la memoria caché de manera mucho más rápida que en la memoria RAM, evitando la pérdida significativa de rendimiento que se experimentaría sin la caché.

La ausencia de memoria caché limitaría drásticamente el rendimiento del sistema, ya que el procesador estaría obligado a depender únicamente de la velocidad de acceso de la memoria RAM. Esto podría resultar en una caída de hasta el 95% en el rendimiento general del sistema.

En las arquitecturas modernas, la memoria caché sigue siendo un componente fundamental para mejorar el rendimiento de los sistemas informáticos. Aunque la velocidad de la memoria principal ha mejorado, el procesador también ha experimentado un aumento significativo en la velocidad y capacidad de procesamiento. Sin embargo, el aumento de velocidad de la CPU ha superado en gran medida el aumento de velocidad de la memoria RAM.

Para mantener un equilibrio entre el procesador y la memoria, se han incorporado múltiples niveles de caché (L1, L2, L3, etc.) en las CPU modernas. Cada nivel de caché es más grande pero más lento que el anterior, y se coloca entre la CPU y la memoria RAM. Esto ayuda a reducir aún más los tiempos de acceso a los datos y las instrucciones, ya que la CPU puede acceder rápidamente a la memoria caché más cercana antes de recurrir a la memoria RAM más lenta. (Gárcia, 2021)

Además, las técnicas de predicción de saltos y prefetching se han vuelto más sofisticadas en las arquitecturas modernas. Estas técnicas anticipan qué datos e instrucciones se requerirán a continuación y los traen a la memoria caché antes de que la CPU los necesite, lo que mejora aún más el rendimiento y la eficiencia del sistema.

 Referencia 

 







Comentarios