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
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 n bytes, sólo podemos usar direcciones multiplos de n
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 2b bytes (siendo b 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 1024 veces más grande que la anterior
Unidad
2n 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 n bits (ancho del bis de datos)
La memoria principal contiene 2nwords (la memoria se direcciona a nivel de palabra)
Si agrupamos estas palabras en grupos de Kwords, nos sale que podemos dividir la memoria en M grupos de Kwords → M=K2npor lo que la memoria principal estará dividida en Mbloques
La memoria caché contiene m líneas que pueden contener Kwords, aunque también cuentan con espacio adicional para metadatos
Hay menos líneas en la caché que bloques en memoria → m<<M
El tamaño de una línea es mayor que el de un bloque → l>>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…
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 4 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)
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_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