Tema 4.1 - Memoria

Introducción


📖
Una diferencia del camino de datos uniciclo respecto del multiciclo reside en la memoria
 
En el camino de datos uniciclo, teníamos dos memorias, una destinada destinada a alamacenar las instrucciones del programa (memoria de instrucciones) y otra destinada a almacenar los datos (memoria de datos)
 
En el camino de datos multiciclo, solo tenemos una única memoria donde se almacenan tando los datos como el programa
 
Esto se debe a que la arquitectura que usa el camino de datos uniciclo está basado en la arquitectura Harvard. Sin embargo, el camino de datos multiciclo está basado en la arquitectura Von Neumann

Jerarquía de memoria


📖
Dado que la memoria no puede alcanzar la velocidad del procesador, esta supone un cuello de botella para la potencia de computación. Por esta razón se introducen distintos tipos de memoria, para paliar esta desventaja
ℹ️
Los distintitos tipos de memoria son accedidos en el orden representado a continuación, desde la punta hasta abajo
  • Registros
    • Mayor rapidez
    • Menor capacidad
  • Memoria terciaria
    • Menor rapidez
    • Mayor capacidad
notion image

Localidad

ℹ️
Localidad
Con el fin de optimizar el proceso de obtener la información, existen dos técnicas a cerca de como tratar de mejorar el rendimiento de las operaciones de lectura
  • Localidad temporal → Si se accede a un dato, es probable que se vuelva a acceder a el más tarde
  • Localidad espacial → Si se accede a un dato, es probable que se acceda a los datos cercanos a él

Hit & Miss

ℹ️
Busqueda a través de las diferentes memorias
Cuando el procesador trata de acceder a un dato (a través de una dirección), lo busca desde el nivel superior de la jerarquía, si el dato no se encuentra ahí, buscará un nivel más abajo hasta que lo encuentre
  • Si el dato se encuentra (hit), la búsqueda termina y el dato es leído
    • Localidad temporal → El dato es elevado en la jerarquía
    • Localidad espacial → Los datos cercanos son elevados en la jerarquía
  • Si el dato no se encuentra (miss), la búsqueda continúa un nivel más abajo
💡
La transferencia de datos se realiza por bloques, aunque el tamaño del bloque puede variar según el nivel en el que nos encontremos

Tecnologías de la Memoria


Endianess

ℹ️
El endianness es un concepto que determina como se guandan los bytes en memoria. Existen dos formas que hacer esto:
  • Big Endian → Dada una dirección, el byte más significativo se almacena primero, y a continuación los bytes sucesivos
  • Little Endian → Dada una dirección, el byte menos significativo se almacena primero, y a continuación los bytes sucesivos

Accesos a memoria alineados

ℹ️
Las direcciones a las cuales podemos acceder para leer o escribir en memoria dependen de la cantidad de bytes a los que queremos acceder. Si queremos acceder a nn bytes, sólo podemos usar direcciones multiplos de nn
  • Acceso a 8 bytes (double-word)Multiplos de 8 (0x0, 0x8)
  • Acceso a 4 bytes (word)Multiplos de 4 (0x0, 0x4, 0x8, 0xc)
  • Acceso a 2 bytes (half-word)Multiplos de 2 (0x0, 0x2, 0x4, 0x6, 0x8, 0xc, 0xe)
  • Acceso a 1 bytes (byte)Multiplos de 1 (todas direcciones)
💡
Los accesos a memoria no alineados consisten en hacer dos llamadas a memoria y se descartan los bits sobrantes. Esta práctica no se suele permitir por su lentitud

Tipos de Memorias

Según el modo de acceso
Memoria de Acceso Aleatorio (Random Access Memory, RAM)
  • El tiempo de acceso a cualquier dato es constante
La RAM es la memoria principal
Memoria de acceso secuencial
  • Los datos se recorren en serie desde el principio
Estas memorias son casetes, cintas de video, etc…
Memoria de acceso directo
  • La información se almacena por zonas, estas permiten un acceso más directo que las de acceso secuencial
Los discos duros magnéticos (HDD)
Memoria de acceso asociativo
  • Se buscan los datos por su valor, no por su dirección
Este es el tipo de memoria de la caché
Según la volatilidad de los datos almacenados
Memoria volátil
En este tipo de memorias, los datos almacenados se borran cuando se corta la corriente
Memoria principal (RAM), caché
Memoria no volátil
Su contenido se mantiene aunque se corte la corriente
HDD, SSD, ROM, DVD, …

Categoría de las memorias según los criterios anteriores

ROM, Read-Only Memory
Estas memorias solo permiten leer los datos. Aunque esto era al principio ya que hoy en día estas memorias permiten ser programables mediante procesos físicos
SRAM, Static RAM
  • Basada en biestables
  • No volátil
  • Más rápidas, Menor capacidad, Más caras
Usadas principalmente para las memorias caché
DRAM, Dynamic RAM
  • Basada en condensadores
  • Volátil
  • Más lenta, Mayor capacidad, Más baratas
Usadas principalmente para la memoria principal

Parámetros de Rendimiento

Tamaño máximo (máxima memoria direccionable)
El tamaño máximo de la memoria de la que podemos disponer son 2b2^b bytes (siendo bb el ancho del bus de direcciones)
Tiempo de ciclo
Tiempo mínimo que debe transcurrir entre dos accesos consecutivos a memoria. Este tiempo se utiliza para para realizar operaciones como: El refresco de las memorias SRAM
Tiempo de acceso (latencia)
Tiempo que se tarda en acceder a un dato.
Tiempo trancurrido desde que se proporciona la dirección y las señal lectura/escritura hasta que se completa dicha operación.
Ancho de banda (bandwidth)
Número de datos por unidad de tiempo que se transmiten. Se conoce como velocidad de transferencia
Se mide en bits por segundo (b/s) o en cualquier multiplo de este: B/s, kB/s, …
Unidades de bits
💡
Cada unidad, es 10241024 veces más grande que la anterior
Unidad
2n2^n Bytes
Byte
0
Kilobytes
10
Megabytes
20
Gigabytes
30
Terabytes
40
Petabytes
50

Memoria Caché


Introducción

📖
La memoria caché proporciona un acceso más rápido a los datos.
ℹ️
Los datos de la memoria caché se almacenan por bloques, estos bloques se ubican en alguna de las lineas de la caché.
 
Nos referiremos a un conjunto de datos fuera de la caché como bloque, y al conjunto dentro de la caché como línea
 
Los bloques, y las líneas de la caché deben tener el mismo tamaño
ℹ️
Teniendo en cuenta que el bus de datos tiene nn bits (ancho del bis de datos)
  • La memoria principal contiene 2n2^n words (la memoria se direcciona a nivel de palabra)
  • Si agrupamos estas palabras en grupos de KK words, nos sale que podemos dividir la memoria en MM grupos de KK words → M=2nK\boxed {M = \frac{2^n}{K}} por lo que la memoria principal estará dividida en MM bloques
  • La memoria caché contiene mm líneas que pueden contener KK words, aunque también cuentan con espacio adicional para metadatos
    • Hay menos líneas en la caché que bloques en memoria → m<<Mm << M
    • El tamaño de una línea es mayor que el de un bloque → l>>Kl >> K
💡
Las líneas de la caché cuentan con espacio adicional respecto del tamaño del bloque para poder almacenar metadatos tales como: Bit de validez
⚠️
La transferencia de datos en todos los niveles de memoria se hace respecto del tamaño del bloque, no de word. Excepto con la CPU, que recibe datos de tamaño word

Tipos de fallos de la Caché: Las Tres C’s

💡
Recordemos que un fallo en el contexto de la caché significa que el dato no se encuentra en este nivel de la memoria
🔴
Compulsory Miss (fallo obligatorio)
Este fallo se da cuando la caché es consultada por primera vez desde su inicio, por lo que todas las líneas están vacías (tienen datos basura). Este fallo es inevitable
🔴
Capacity Miss (fallo por capacidad)
Este fallo se da cuando todas las lineas están ocupadas por lo que aunque no se encuentre el dato, tampoco podremos traerlo más allá de este nivel
🔴
Conflict Miss (fallo por conflicto)
Este fallo se da cuando una misma línea de caché corresponde a varios bloques de memoria principal y a su vez estos se están reemplazando continuamente

Diseño de una Memoria Caché

Función de correspondencia

ℹ️
Dado que el número de líneas de la caché es inferior al número de bloques de la memoria principal, existirá un colisón entre bloques ya que debemos asignar a más de un bloque, la misma línea en la cache.
 
La función de correspondencia establece el criterio que seguiremos para asignar a un bloque, una línea en la caché. Existen varias estrategias (funciones de correspondencia) que podemos seguir…
📍
Estrategia de correspondencia directa
📍
Estategia de correspondencia totalmente asociativa
📍
Estrategia de correspondencia asociativa por conjuntos
💡
Se conoce como Vía a las conexiones de un bloque con las líneas de la caché
  • Correspondencia directa → 1 vía
  • Correspondencia totalmente asociativa → tantas vías como líneas en la caché
  • Correspondencia asociativa por conjuntos → tantas vías como el tamaño de los conjuntos

Algoritmos de reemplazo

📖
El algoritmo de reemplazo establece el criterio que se utilizará para determinar en qué línea, de entre las accesibles a través de las vías de dicho bloque, debemos almacenar el dato
 
Diferentes algoritmos de reemplazo:
Aleatorio
La línea se elige al azar entre las posibles a través de las vías de dicho bloque. Esta técnica es casi tan buena como las otras
Least-Recently Used (LRU)
Esta técnica utiliza el criterio de localidad temporal, siendo así que los datos que llevan más tiempo sin ser referenciados, son reemplazados
 
Require añadir a la linea unos bits de uso, estos consisten en unos contadores que llevan la cuenta de qué líneas han sido las más recientemente accedidas
Least-Frequently Used (LFU)
A diferencia del LRU, este algoritmo reemplazará los datos que menos veces han sido referenciados, sin importar si han sido utilizados recientemente
 
Require añadir unos bits a modo de contador de aciertos
First-In-First-Out (FIFO)
Este algoritmo almacena los datos como si estos pertenecieran a una cola, por lo que los datos se almacenan en la línea del dato que lleva más tiempo en la caché
Óptimo (ideal)
Este algoritmo consiste en reemplazar el dato que no va a ser utilizado durante más tiempo.
 
Este algoritmo no siempre es posible de implementar ya que requiere que podamos hacer una previsión de qué datos vamos a referenciar y cuando

Políticas de Lectura/Escritura

🟢
Acierto en la caché al leer
Este caso no supone ningún problema para el flujo normal del programa
🔴
Fallo en la caché al leer
Cuando ocurre un fallo, se consulta el dato deseado en un nivel inferior de la jerarquía. El ciclo de la instrucción actual es reiniciado debido a que el acceso al dato cuando este se encuentra en unidades inferiores en la jerarquía puede tardar varios ciclos
💡
Si lo que estamos consultando es una instrucción, se debe restar 44 al valor actual de PC ya que este se incrementa al principio del ciclo
🟢
Acierto en la caché al escribir
Cuando ocurre un acierto en el acceso a un dato el cual deseamos actualizar, debemos decidir cuando actualizaremos el dato en memoria principal
Write-through (inmediatamente)
El dato se actualiza tanto en la caché como en la memoria principal
  • Se utiliza un buffer de escritura
 
Write-back (retardado)
El dato solo se escribe en caché, y solo se vuelca en la memoria principal cuando haya que reemplazar el dato en la caché
  • Bit sucio (dirty bit, D) → Este es un bit en memoria principal que indica que el bloque tiene modificaciones pendientes
🔴
Fallo en la caché al escribir
En estos casos existen dos estrategias
Write Allocate (fetch on write)
Se trae el bloque a la caché y luego se gestiona como un acierto. Se suele combinar con write-back
 
No-Write Allocate (write around)
Se modifica el bloque en la memoria principal pero no en la caché. Se suele combinar con write-through
 

Tamaño de la línea

ℹ️
El tamaño de la línea dependerá de la eleción que hemos hecho de las estrategias mencionadas anteriormente…
  • Función de correspondencia
  • Algoritmo de reemplazo
 
Cada línea está compuesta por
  • Bit de validez
  • Bit de suciedad
  • Bit(s) de acceso (Solo para el algoritmo de reemplazo: LRU)
  • Etiqueta (El tamaño dependerá de la función de correspondencia)
  • Datos (Contenido del bloque almacenada en la línea)

Otros aspectos de las cachés

Niveles de la caché en la jerarquía:
  • Uno
  • Varios
Hoy en día, se cuentan con varios niveles de caché con a cada cual más rápida que la inferiror
Cachés para datos e instrucciones:
  • Unificada
  • Separada
Podemos contar con cachés separadas para instrucciones y datos
Cachés para los núcleos del procesador:
  • Compartido
  • De uso exclusivo
Las caché pueden ser exclusivas de un core o compartida por los diferentes cores
Ubicación física de la caché:
  • On-chip
  • Off-chip
La caché puede estar integrada al procesador, o en un chip externo

Medición de rendimiento

ℹ️
Este parámetro mide el tiempo medio de acceso a un dato en memoria: AMAT (Average memory access time)
Opción 1 (Fórmula de la media ponderada)
  • tasa_acierto → Proporción de aciertos (tanto por uno)
  • tiempo_acierto → Tiempo necesario para acceder a un dato en cache (acierto)
  • tasa_fallo → Proporción de fallos (tanto por uno)
  • tiempo_fallotiempo_acierto ++ penalizacion_fallo
AMAT=tasa_acierto×tiempo_acierto+tasa_fallo×tiempo_falloAMAT =\\tasa\_acierto \times tiempo\_acierto + tasa\_fallo \times tiempo\_fallo
Opción 2
  • tiempo_acierto → Tiempo necesario para acceder a un dato en cache (acierto)
  • tasa_fallo → Proporción de fallos (tanto por uno)
  • penalizacion_fallo → Tiempo extra necesario tras un fallo para acceder a memoria (penalización_fallo)
AMAT=tiempo_acierto+tasa_fallo×penalizacion_falloAMAT = \\ tiempo\_acierto + tasa\_fallo \times penalizacion\_fallo
⚠️
La penailzacion_fallo / tiempo_fallo hay que multiplicarla por el número de palabras por bloque. Ya que cada fallo require mover todos un bloque palabra por palabra