Está en la página 1de 22

Digital Design and

Computer Architecture

David Money Harris & Sarah L. Harris


Morgan Kaufman - 2007

Traducción parcial del Capítulo 8

Dr. Ing. Armando D. Assandri

Cátedra Electrónica Digital II

2013
8

Sistemas de Memoria

8.1 INTRODUCCIÓN

El rendimiento de un sistema de cómputo depende del sistema de memoria así como de la


microarquitectura del procesador. En el Capítulo 7 se asumió un sistema de memoria ideal
que podría ser accedido en un solo ciclo de reloj. Sin embargo, esto sólo podría ser cierto para
una memoria muy pequeña, ¡o un procesador muy lento! Los procesadores antiguos eran rela-
tivamente lentos, de manera que la memoria era capaz de seguirles el ritmo. Pero la velocidad
del procesador se ha incrementado a una tasa más rápida que la de la memoria. Las memorias
DRAM actualmente son de 10 a 100 veces más lentas que los procesadores. La brecha cre-
ciente entre las velocidades de los procesadores y de la memoria DRAM demanda sistemas de
memoria cada vez más ingeniosos, para tratar de aproximarse a una memoria que sea tan rá-
pida como el procesador. Este capítulo investiga los sistemas de memoria prácticos y conside-
ra las relaciones de compromiso entre velocidad, capacidad y costo.

El procesador se comunica con el sistema de memoria a través de una interfaz a memoria. La


Figura 8.1 muestra un interfaz a memoria simple usada en el procesador multiciclo MIPS. El
procesador envía al sistema de memoria una dirección por el bus de Direcciones. Para una
lectura, MemWrite es 0 y la memoria retorna un dato por el bus ReadData. Para una escritura,
MemWrite es 1 y el procesador envía datos a memoria por el bus WriteData.

El asunto principal en el diseño del sistema de memoria se puede explicar en términos genera-
les usando una metáfora de libros en una biblioteca. Una biblioteca contiene muchos libros en
las estanterías. Si alguien está escribiendo un ensayo sobre el significado de los sueños, podría
ir a la biblioteca1 y sacar de la estantería La Interpretación de los Sueños de Freud y llevarlo a
su cubículo. Después de echarle una mirada, podría ponerlo en su lugar y sacar La Psicología
del Inconsciente de Jung. Luego podría volver por otra cuota de La Interpretación de los Sue-
ños, seguida de otro viaje a las estanterías por El Ego y Yo de Freud. Muy pronto se cansaría
de caminar desde su cubículo a las estanterías. Si es inteligente, podría ahorrar tiempo

1
Nos damos cuenta que el uso de la biblioteca está cayendo en picada entre los estudiantes universitarios debido
a Internet. Pero también creemos que las bibliotecas contienen grandes tesoros de conocimiento humano ganado
con mucho esfuerzo que no está disponible en formato electrónico. Esperamos que la búsqueda en la Web no
desplace totalmente el arte de investigar en la biblioteca.

1
Figura 8.1 Interfaz a Memoria

manteniendo los libros en su cubículo en lugar de andar llevándolos de aquí para allá. Ade-
más, cuando saca un libro de Freud, también podría sacar varios de sus otros libros del mismo
estante.

Esta metáfora enfatiza el principio, introducido en la Sección 6.2.1, de hacer rápido el caso
común. Manteniendo en su cubículo los libros que ha usado recientemente o que probable-
mente podría usar en el futuro, se reduce la cantidad de viajes consumidores de tiempo a las
estanterías. En particular, se usan los principios de localidad temporal y espacial. Localidad
temporal significa que si ha usado recientemente un libro, es probable que lo use de nuevo
pronto. Localidad espacial significa que cuando usa un libro en particular, es probable que se
interese por otros libros del mismo estante.

La biblioteca por sí misma hace rápido el caso común usando este principio de localidad. La
biblioteca no tiene ni el espacio de estantes ni el presupuesto para alojar todos los libros del
mundo. En vez de eso, almacena algunos de los libros menos usados en el sótano. Además,
puede tener un acuerdo de préstamo interbibliotecario con bibliotecas cercanas de manera que
puede ofrecer más libros de los que físicamente tiene.

En resumen, se obtienen los beneficios de tener una gran colección y acceso rápido a los li-
bros más usados por medio de una jerarquía de almacenamiento. Los libros más usados están
en su cubículo. Una colección más grande está en las estanterías. Y una colección aún más
grande está disponible, con aviso previo, del sótano o de otras bibliotecas. De forma similar,
los sistemas de memoria usan una jerarquía de almacenamiento para acceder rápidamente a
los datos más usados, manteniendo aún la capacidad de almacenar grandes cantidades de da-
tos.

Los subsistemas de memoria usados para construir esta jerarquía fueron presentados en la
sección 5.5. Las memorias de las computadoras están construidas principalmente con RAM
dinámica (DRAM) y estática (SRAM). Idealmente, el sistema de memoria de una computado-
ra es rápido, grande y barato. En la práctica, una memoria individual sólo tiene dos de estos
tres atributos; o es lenta, o pequeña, o cara. Pero los sistemas de computación pueden aproxi-
mar el ideal combinando una memoria rápida, pequeña y barata con una memoria lenta, gran-
de y barata. La memoria rápida almacena los datos e instrucciones más usados, de manera que
en promedio el sistema de memoria parece rápido. La memoria grande almacena el resto de
los datos e instrucciones, de manera que la capacidad total es grande. La combinación de dos

2
memorias baratas es mucho menos cara que una única memoria grande y rápida. Estos princi-
pios se extienden al uso de toda una jerarquía de memorias de capacidad creciente y velocidad
decreciente.

La memoria de una computadora generalmente está construida con chips de DRAM. En 2006,
una PC típica tenía una memoria principal que constaba de 256 MB a 1 GB de DRAM, y la
DRAM costaba cerca de U$S 100 por gigabyte (GB). Los precios de las DRAMs han bajado
un 30% por año durante las últimas tres décadas, y la capacidad de la memoria ha crecido a la
misma tasa, de manera que el costo total de la memoria en una PC ha permanecido más o me-
nos constante. Desafortunadamente, la velocidad de las DRAMs ha mejorado sólo como un
7% por año, mientras que el rendimiento de un procesador ha mejorado a una tasa de un 30%
a un 50% por año, como se muestra en la Figura 8.2. La gráfica muestra las velocidades del
procesador y la memoria con las velocidades de 1980 como punto de partida. En 1980, las
velocidades del procesador y la memoria eran las mismas. Pero el rendimiento ha divergido
desde entonces, con las memorias retrasándose gravemente.

Figura 8.2 Rendimiento divergente de procesador y memoria

La DRAM pudo mantener el ritmo con los procesadores en los ´70 y a principios de los ´80,
pero desgraciadamente ahora es muy lenta. El tiempo de acceso de una DRAM es de uno a
dos órdenes de magnitud más largo que el tiempo de ciclo de un procesador (decenas de na-
nosegundos, comparado con menos de un nanosegundo).

Para contrarrestar esta tendencia, las computadoras almacenan los datos e instrucciones más
usados en una memoria rápida pero más pequeña, llamada caché. La caché usualmente está
construida con SRAM en el mismo chip que el procesador. La velocidad de la caché es com-
parable con la del procesador, debido a que la SRAM es inherentemente más rápida que la
DRAM, y debido a que la memoria en el chip elimina los prolongados retardos causados por
el recorrido a y desde un chip separado. En 2006, los costos de la SRAM en el chip eran del

3
orden de los U$S10.000/GB, pero la caché es relativamente pequeña (de kilobytes a unos po-
cos megabytes), por lo que el costo total es bajo. Las cachés pueden almacenar instrucciones y
datos, pero se referirá a su contenido genéricamente como “datos”.

Si el procesador solicita datos que están disponibles en la caché, se retornan rápido. Esto se
llama un acierto (hit) de caché. En caso contrario, el procesador recupera los datos de la me-
moria principal (DRAM). Esto se llama un fallo (miss) de caché. Si la caché acierta la mayor
parte del tiempo, el procesador rara vez tiene que esperar a la memoria principal lenta, y el
tiempo de acceso promedio es bajo.

El tercer nivel en la jerarquía de memoria es el disco duro, o unidad de disco duro (hard dri-
ve). De la misma manera que una biblioteca usa el sótano para almacenar libros que no caben
en las estanterías, los sistemas de cómputo usan el disco duro para almacenar datos que no
caben en la memoria principal. En 2006, un disco duro costaba menos de 1 U$S/GB y tenía
un tiempo de acceso de unos 10 ms. El costo de los discos duros ha disminuido un 60%/año,
pero los tiempos de acceso apenas mejoraron. El disco duro proporciona la ilusión de tener
más capacidad que la que realmente existe en la memoria principal. De esa manera se deno-
mina memoria virtual. Como los libros en el sótano, lleva un tiempo largo acceder a los datos
de la memoria virtual. La memoria principal, también llamada memoria física, contiene un
subconjunto de la memoria virtual. Por lo tanto, la memoria principal se puede ver como una
caché de los datos más usados del disco duro.

La Figura 8.3 resume la jerarquía de memoria del sistema de cómputo tratado en el resto de
este capítulo. El procesador primero busca el dato en una caché pequeña, pero rápida, ubicada
en el mismo chip. Si el dato no está disponible en la caché, el procesador luego mira en la
memoria principal. Si el dato tampoco está ahí, el procesador busca el dato en la memoria
virtual en el disco duro, grande, pero lento. La Figura 8.4 ilustra este compromiso entre capa-
cidad y velocidad en la jerarquía de memoria y lista los costos y tiempos de accesos típicos
con la tecnología de 2006. A medida que disminuye el tiempo de acceso, se incrementa la
velocidad.

Figura 8.3 Una jerarquía de memoria típica

La Sección 8.2 presenta el análisis del rendimiento del sistema de memoria. En la Sección 8.3
se exploran varias organizaciones de caché, y en la Sección 8.4 se profundiza en los sistemas

4
de memoria virtual. Para concluir, este capítulo explora cómo pueden acceder los procesado-
res a los dispositivos de entrada y salida, tales como teclados y monitores, de una manera muy
similar a como acceden a memoria. La Sección 8.5 investiga tal E/S mapeada en memoria.

Figura 8.4 Componentes de la jerarquía de memoria,


con características típicas del 2006

8.2 ANÁLISIS DEL RENDIMIENTO DEL SISTEMA DE MEMORIA


Los diseñadores (y los que compran computadoras) necesitan formas cuantitativas de medir el
rendimiento de los sistemas de memoria para evaluar los compromisos costo/beneficio de
diversas alternativas. Las métricas del rendimiento del sistema de memoria son la tasa de fa-
llos (miss rate) o la tasa de aciertos (hit rate) y el tiempo de acceso promedio a memoria. Las
tasas de fallos y aciertos se calculan como:

(8.1)

Ejemplo 8.1 CÁLCULO DEL RENDIMIENTO DE LA CACHÉ


Suponga que un programa tiene 2000 instrucciones de acceso a datos (cargas y almacena-
mientos), y 1250 de estos valores de los datos requeridos se encuentran en la caché. Los otros

5
750 valores de los datos son suministrados al procesador por la memoria principal o la memo-
ria en disco. ¿Cuáles son las tasas de fallos y aciertos de la caché?

Solución: La tasa de fallos es 750/2000 = 0,375 = 37,5%. La tasa de aciertos es 1250/2000 =


0,625 = 1 – 0,375 = 62,5%

El tiempo promedio de acceso a memoria (average memory access time – AMAT) es el tiempo
promedio que un procesador debe esperar a la memoria por cada instrucción de carga o alma-
cenamiento. En el sistema de cómputo típico de la Figura 8.3, el procesador primero mira los
datos que están en la caché. Si la caché falla, el procesador luego mira en la memoria princi-
pal. Si la memoria principal falla, el procesador accede a la memoria virtual en el disco duro.
Así, el AMAT se calcula como:

( ) (8.2)

Donde , y son los tiempos de acceso de la caché, la memoria principal y la


memoria virtual, y y son las tasas de fallos de la caché y de la memoria prin-
cipal, respectivamente.

Ejemplo 8.2 CÁLCULO DEL TIEMPO PROMEDIO DE ACCESO A MEMORIA


Suponga que un sistema de cómputo tiene una organización de memoria con una jerarquía de
sólo dos niveles, una caché y memoria principal. ¿Cuál es el tiempo promedio de acceso a
memoria dados los tiempos de acceso y tasas de fallos mostrados en la Tabla 8.1?

Solución: El tiempo promedio de acceso a memoria es 1 + 0,1(100) = 11 ciclos.

Tabla 8.1 Tiempos de acceso y tasas de fallos

Nivel de Tiempo de Acceso Tasa de


Memoria (Ciclos) Fallos
Caché 1 10%
Memoria Principal 100 0%

Ejemplo 8.3 CÓMO MEJORAR EL TIEMPO DE ACCESO


Un tiempo promedio de acceso a memoria de 11 ciclos significa que el procesador gasta diez
ciclos esperando los datos por cada ciclo que realmente los usa. ¿Qué tasa de fallos de la ca-
ché se requiere para reducir el tiempo promedio de acceso a memoria a 1,5 ciclos dados los
tiempos de acceso de la Tabla 8.1?

Solución: Si la tasa de fallos es m, el tiempo promedio de acceso es 1 + 100m. Fijando este


tiempo en 1,5 y resolviendo para m, se requiere una tasa de fallos de la caché de 0,5%.

6
Como palabras de advertencia, las mejoras del rendimiento no siempre podrían ser tan buenas
como suenan. Por ejemplo, haciendo el sistema de memoria diez veces más rápido no necesa-
riamente va a hacer que un programa de la computadora se ejecute diez veces más rápido. Si
el 50% de las instrucciones de un programa son cargas y almacenamientos, una mejora de 10
veces en el sistema de memoria sólo significa una mejora de 1,82 veces en el rendimiento del
programa. Este principio general se llama Ley de Amdahl, que dice que el esfuerzo empleado
en incrementar el rendimiento de un subsistema vale la pena sólo si el subsistema afecta un
porcentaje alto del rendimiento total.

8.3 CACHÉS
Una caché contiene datos de memorias usados comúnmente. La cantidad de palabras de datos
que puede contener es llamada la capacidad, C. Debido a que la capacidad de la caché es más
pequeña que la de la memoria principal, el diseñador de sistemas de cómputo debe elegir qué
subconjunto de la memoria principal se mantiene en la caché.

Cuando el procesador intenta acceder a un dato, primero verifica si está en la caché. Si la ca-
ché acierta, el dato está disponible de inmediato. Si la caché falla, el procesador busca el dato
en la memoria principal y lo coloca en la caché para uso futuro. Para alojar el dato nuevo, la
caché debe reemplazar un dato viejo. Esta sección investiga estos temas del diseño de cachés
respondiendo las siguientes preguntas: (1) ¿Qué datos se tienen en la caché? (2) ¿Cómo se
encuentran los datos? y (3) ¿Qué dato se reemplaza para hacerle lugar a un dato nuevo cuando
la caché está llena?

Cuando se lean las próximas secciones, tenga en mente que la motivación principal al respon-
der estas preguntas es la localidad espacial y temporal inherente de los accesos a los datos en
la mayoría de las aplicaciones. Las cachés usan la localidad espacial y temporal para predecir
qué dato se necesitará a continuación. Si un programa accede a los datos en un orden aleato-
rio, no se beneficiaría de la caché.

Como se explica en las secciones siguientes, las cachés se especifican por su capacidad (C),
cantidad de conjuntos (S), tamaño del bloque (b), cantidad de bloques (B) y grado de asociati-
vidad (N).

Aunque el texto se enfoca en las cargas de la caché de datos, los mismos principios de aplican
a las búsquedas en la caché de instrucciones. Las operaciones de almacenamiento en la caché
de datos son similares y se tratan con más detalle en la Sección 8.3.4.

8.3.1 ¿Qué Datos se Tienen en la Caché?


Una caché ideal podría anticipar todos los datos requeridos por el procesador y buscarlos an-
tes de tiempo en la memoria principal, de manera que la caché tenga una tasa de fallos de ce-
ro. Debido a que es imposible predecir el futuro con exactitud perfecta, la caché debe suponer
qué datos serán necesarios en base al patrón pasado de accesos a memoria. En particular, la
caché explota la localidad temporal y espacial para obtener una tasa de fallos baja.
7
Recuerde que la localidad temporal significa que es probable que el procesador acceda a una
porción de datos de nuevo en breve si ha accedido a esos datos recientemente. Por lo tanto,
cuando el procesador carga o almacena datos que no están en la caché, los datos se copian en
la caché desde la memoria principal. Las solicitudes subsecuentes a los datos acertarán en la
caché.

Recuerde que la localidad espacial significa que, cuando el procesador acceda a una porción
de datos, también es probable que se acceda a datos en ubicaciones cercanas de la memoria.
Por lo tanto, cuando la caché va a buscar una palabra en la memoria, también busca varias
palabras adyacentes. Este grupo de palabras se llama bloque de caché. La cantidad de pala-
bras que hay en el bloque de caché, b, se llama tamaño del bloque. Una caché de capacidad C
contiene B = C/b bloques.

Los principios de localidad temporal y espacial han sido verificados experimentalmente en


programas reales. Si se usa una variable en un programa, es probable que se use de nuevo la
misma variable, creando localidad temporal. Si se usa un elemento de una matriz, es probable
que se usen otros elementos de la misma matriz, creando localidad espacial.

8.3.2 ¿Cómo se Encuentran los Datos?


Una caché está organizada en S conjuntos, cada uno de los cuales tiene uno o más bloques de
datos. La relación entre la dirección del dato en memoria principal y la ubicación de ese dato
en la caché se llama función de correspondencia (mapping). Cada dirección de memoria se
corresponde con exactamente un conjunto en la caché. Algunos de los bits de dirección se
usan para determinar qué conjunto de la caché contiene el dato. Si el conjunto contiene más
de un bloque, el dato puede estar almacenado en cualquier bloque del conjunto.

Las cachés están categorizadas en base a la cantidad de bloques en un conjunto. En una caché
con correspondencia directa (direct mapped), cada conjunto contiene exactamente un bloque,
de manera que la caché tiene S = B conjuntos. Así, una dirección particular de memoria prin-
cipal corresponde a un único bloque en la caché. En una caché asociativa de conjuntos de N
vías, cada conjunto contiene N bloques. La dirección todavía se corresponde a un único con-
junto, con S = B/N conjuntos. Pero el dato de esa dirección puede ir en cualquiera de los N
bloques en ese conjunto. Una caché completamente asociativa (fully associative) tiene sólo un
conjunto (S = 1). El dato puede ir en cualquiera de los B bloques del conjunto. Por consi-
guiente, una caché completamente asociativa es otro nombre para una caché asociativa de
conjuntos de B vías.

Para ilustrar estas organizaciones de la caché, se considerará el sistema de memoria del MIPS
con direcciones y palabras de 32 bits. La memoria es direccionable por byte, y cada palabra
tiene cuatro bytes, por lo que la memoria consta de 230 palabras alineadas en los límites de
palabra. Se analizan cachés con capacidad para 8 palabras (C), por simplicidad. Se comienza
con un tamaño de bloque de una palabra (b), y luego se generaliza para bloques más grandes.

8
Caché de Correspondencia Directa
Una caché de correspondencia directa tiene un bloque en cada conjunto, por lo que está orga-
nizada en S = B conjuntos. Para entender la correspondencia de las direcciones de memoria
con los bloques de memoria, imagine como que la memoria principal se está haciendo corres-
ponder con bloques de b palabras, justo como es la caché. Una dirección en el bloque 0 de la
memoria principal se corresponde con el conjunto 0 de la caché. Una dirección en el bloque 1
de la memoria principal se corresponde con el conjunto 1 de la caché, y así sucesivamente
hasta que una dirección en el bloque B – 1 de la memoria principal se corresponde con el con-
junto B – 1 de la caché. No hay más bloques en la caché, por lo que la función de correspon-
dencia se reinicia en forma cíclica, de manera que el bloque B de la memoria principal se co-
rresponde con el conjunto 0 de la caché.

Figura 8.5 Función de correspondencia entre la memoria principal


y una caché de correspondencia directa

Esta función de correspondencia se ilustra en la Figura 8.5 para una caché de correspondencia
directa con una capacidad de ocho palabras y un tamaño de bloque de una palabra. La caché
tiene ocho conjuntos, cada uno de los cuales contiene un bloque de una palabra. Los dos bits
menos significativos de la dirección siempre están en 00, debido a que las direcciones están
alineadas por palabra. Los siguientes log2 8 = 3 bits indican en qué conjunto se corresponde
la dirección de memoria. Así, todos los datos que están en las direcciones 0x00000004,
0x00000024, …, 0xFFFFFFF4 se corresponden con el conjunto 1. De igual modo, todos los

9
datos que están en las direcciones 0x00000010, … , 0xFFFFFFF0 se corresponden con el
conjunto 4, etc. Cada dirección de la memoria principal se corresponde con exactamente un
conjunto en la caché.

Ejemplo 8.4 CAMPOS DE LA CACHÉ


¿A cuál conjunto de la caché le corresponde la dirección 0x00000014 en la Figura 8.5? Men-
cione otra dirección que se corresponda con el mismo conjunto.

Solución: Los dos bits menos significativos de la dirección son 00, debido a que la dirección
está alineada por palabra. Los siguientes tres bits son 101, por lo que la palabra se correspon-
de con el conjunto 5. Todas las palabras con las direcciones 0x34, 0x54, 0x74, …,
0xFFFFFFF4 se corresponden con el mismo conjunto.

Debido a que muchas direcciones se corresponden con un único conjunto, la caché también
debe seguir la pista de las direcciones de los datos realmente contenidos en cada conjunto.
Los bits menos significativos de la dirección especifican cuál conjunto tiene el dato. Los bits
más significativos restantes se denominan la etiqueta e indican cuál de las muchas posibles
direcciones está contenida en ese conjunto.

En el ejemplo anterior, los dos bits menos significativos de la dirección de 32 bits se denomi-
nan el desplazamiento de byte (byte offset), debido a que indican el byte dentro de una pala-
bra. Los próximos tres bits se denominan bits de conjunto, debido a que indican el conjunto
con el que se hace corresponder la dirección. (En general, la cantidad de bits de conjunto es
log2 S). Los restantes 27 bits de etiqueta indican la dirección de memoria del dato almacenado
en un conjunto dado de la caché. La Figura 8.6 muestra los campos de la caché para la direc-
ción 0xFFFFFFE4. Se corresponde con el conjunto 1 y su etiqueta son todos unos.

Figura 8.6 Campos de la caché para la dirección 0xFFFFFFE4 cuando


se hace la correspondencia de la caché de la Figura 8.5

10
Ejemplo 8.5 CAMPOS DE LA CACHÉ
Encuentre la cantidad de bits de conjunto y etiqueta para una memoria caché de correspon-
dencia directa con 1024 (210) conjuntos y un tamaño de bloque de una palabra. El tamaño de
la dirección es de 32 bits.

Solución: Una caché con 210 conjuntos requiere log2 (210) = 10 bits de conjunto. Los dos bits
menos significativos de la dirección son el desplazamiento de byte, y los 32 – 10 – 2 = 20 bits
restantes forman la etiqueta.

A veces, como cuando la computadora arranca por primera vez, los conjuntos de la caché no
contienen ningún dato. La caché usa un bit de válido (valid bit) en cada conjunto para indicar
si el conjunto tiene un dato significativo. Si el bit de válido es 0, el contenido no tiene sentido.

Figura 8.7 Caché de correspondencia directa de 8 conjuntos

La Figura 8.7 muestra el hardware para la caché de correspondencia directa de la Figura 8.5.
La caché se arma como una SRAM de ocho entradas. Cada entrada, o conjunto, contiene una
línea que consta de 32 bits de dato, 27 bits de etiqueta y 1 bit de válido. La caché se accede
usando la dirección de 32 bits. Los dos bits menos significativos, los bits de desplazamiento
de byte, se ignoran para los accesos a palabra. Los próximos tres bits, los bits de conjunto,
especifican la entrada o conjunto en la caché. Una instrucción de carga lee la entrada especifi-
cada de la caché y verifica los bits de etiqueta y válido. Si la etiqueta es igual a los 27 bits de
dirección y el bit de válido está en 1, la caché acierta y se retorna el dato al procesador. En

11
caso contrario, la caché falla y el sistema de memoria debe buscar el dato en la memoria prin-
cipal.

Ejemplo 8.6 LOCALIDAD TEMPORAL CON UNA CACHÉ DE CORRESPONDENCIA


DIRECTA

En las aplicaciones los lazos son una fuente común de localidad temporal y espacial. Usando
las caché de ocho entradas de la Figura 8.7, muestre el contenido de la caché después de eje-
cutar el siguiente lazo tonto en código ensamblador de MIPS. Asuma que la caché está vacía
inicialmente. ¿Cuál es la tasa de fallos?

addi $t0, $0, 5


loop: beq $t0, $0, done
lw $t1, 0x4($0)
lw $t2, 0xC($0)
lw $t3, 0x8($0)
addi $t0, $t0, -1
j loop
done:

Solución: El programa contiene un lazo que se repite cinco iteraciones. Cada iteración invo-
lucra tres accesos a memoria (cargas), dando un total de 15 accesos a memoria. La primera
vez que se ejecuta el lazo, la caché está vacía y los datos deben ser buscados en la ubicaciones
de memoria principal 0x4, 0xC y 0x8 y llevados a los conjuntos 1, 3 y 2 de la caché, respecti-
vamente. Sin embargo, la próximas cuatro veces que se ejecuta el lazo, los datos se encuen-
tran en la caché. La Figura 8.8 muestra el contenido de la caché durante la última petición a la
dirección de memoria 0x4. Las etiquetas están todas en 0 debido a que los 27 bits más signifi-
cativos de las direcciones son 0. La tasa de fallos es 3/15 = 20%.

Figura 8.8 Contenido de una caché de correspondencia directa

12
Cuando dos direcciones que se han accedido recientemente se corresponden con el mismo
bloque de la caché, ocurre un conflicto, y la dirección accedida más recientemente desaloja a
la anterior del bloque. Las cachés de correspondencia directa sólo tienen un bloque en cada
conjunto, de manera que dos direcciones que se corresponden con el mismo conjunto siempre
causan un conflicto. El siguiente ejemplo ilustra los conflictos.

Ejemplo 8.7 CONFLICTO DE BLOQUE DE LA CACHÉ


¿Cuál es la tasa de fallos en la caché de correspondencia directa de la Figura 8.7 cuando se
ejecuta el siguiente lazo? Asuma que la caché está vacía inicialmente.

addi $t0, $0, 5


loop: beq $t0, $0, done
lw $t1, 0x4($0)
lw $t2, 0x24($0)
addi $t0, $t0, -1
j loop
done:

Solución: Las dos direcciones 0x4 y 0x24 se corresponden con el conjunto1. Durante la eje-
cución inicial del lazo, se carga en el conjunto 1 de la caché el dato contenido en la dirección
0x4. Luego el dato de la dirección 0x24 se carga en el conjunto 1, desalojando el dato de la
dirección 0x4. Con la segunda ejecución del lazo, el patrón de repite y la caché debe buscar de
nuevo el dato de la dirección 0x4, desalojando el dato de la dirección 0x24. Las dos direccio-
nes entran en conflicto y la tasa de fallos es del 100%.

Caché Asociativa de Conjuntos Multivía


Una caché asociativa de conjuntos de N vías reduce los conflictos proporcionando N bloques
en cada conjunto, donde se podrían encontrar los datos que se hacen corresponder con ese
conjunto. Cada dirección de memoria todavía se hace corresponder con un conjunto específi-
co, pero lo puede hacer en cualquiera de los N bloques del conjunto. Por consiguiente, una
caché de correspondencia directa es otro nombre para una caché asociativa de conjuntos de
una vía. A N también se le llama el grado de asociatividad de la caché.

La Figura 8.9 muestra el hardware para una caché asociativa de conjuntos de C = 8 palabras y
N = 2 vías. La caché ahora sólo tiene S = 4 conjuntos en lugar de 8.

Así, se usan sólo log2 4 = 2 bits de conjunto en lugar de 3 para seleccionar el conjunto. La
etiqueta se incrementa de 27 a 28 bits. Cada conjunto contiene dos vías o grados de asociati-
vidad. Cada vía consta de un bloque de dato y los bits de etiqueta y válido. La caché lee los
bloques de las dos vías en el conjunto seleccionado y verifica los bits de etiqueta y válido para

13
un acierto. Si se produce un acierto en una de las dos vías, un multiplexor selecciona el dato
de esa vía.

Figura 8.9 Caché asociativa de conjuntos de dos vías

Las cachés asociativas de conjuntos generalmente tienen tasas de fallos más bajas que las ca-
chés de correspondencia directa de la misma capacidad, debido a que tienen menos conflictos.
Sin embargo, las cachés asociativas de conjuntos usualmente son más lentas, y de alguna ma-
nera más caras de construir, debido al multiplexor de salida y a los comparadores adicionales.
También plantean la pregunta de cuál vía reemplazar cuando las dos vías están llenas; esto se
trata más a fondo en la sección 8.3.3. La mayoría de los sistemas comerciales usan cachés
asociativas de conjuntos.

Ejemplo 8.8 TASA DE FALLOS DE LA CACHÉ ASOCIATIVA DE CONJUNTOS


Repetir el Ejemplo 8.7 usando la caché asociativa de conjunto de dos vías y ocho palabras de
la Figura 8.9.

Solución: Los dos accesos a memoria, para las direcciones 0x4 y 0x24, se corresponden con
el conjunto 1. Sin embargo, la caché tiene dos vías, por lo que puede alojar los datos de ambas
direcciones. Durante el primer bucle de la iteración, la caché vacía falla con las dos direccio-
nes y carga ambas palabras de datos en las dos vías del conjunto 1, como se muestra en la
Figura 8.10. En las próximas cuatro iteraciones, la caché acierta. Por consiguiente, la tasa de
fallos es 2/10 = 20%. Hay que recordar que la caché de correspondencia directa del mismo
tamaño del Ejemplo 8.7 tuvo una tasa de fallos del 100%.

14
Figura 8.10 Contenido de una caché asociativa de conjuntos de dos vías

Caché Completamente Asociativa


Una caché completamente asociativa contiene un único conjunto con B vías, donde B es la
cantidad de bloques. Una dirección de memoria puede corresponder a un bloque en cualquie-
ra de estas vías. Una caché completamente asociativa es otro nombre para un caché asociativa
de conjuntos de B vías con un conjunto.

La Figura 8.11 muestra la matriz de SRAM de una caché completamente asociativa con ocho
bloques. Ante el requerimiento de un dato, se deben hacer ocho comparaciones de etiqueta
(no mostradas), debido a que el dato puede estar en cualquier bloque. De forma similar, un
multiplexor 8:1 selecciona el dato correcto si se produce un acierto. La cachés completamente
asociativas suelen tener la menor cantidad de fallos por conflictos para una capacidad de ca-
ché dada, pero requieren más hardware para realizar las comparaciones de etiqueta adiciona-
les. Son más apropiadas para cachés relativamente pequeñas debido al gran número de com-
paradores requeridos.

Figura 8.11 Caché completamente asociativa de ocho bloques

Tamaño del Bloque


Los ejemplos anteriores fueron capaces de aprovechar sólo la localidad temporal, debido a
que el tamaño del bloque fue de una palabra. Para explotar la localidad espacial, una caché
usa bloques más grandes para contener varias palabras consecutivas.

La ventaja de un tamaño de bloque mayor a uno es que cuando se produce un fallo y se trae la
palabra a la caché, también se traen las palabras adyacentes del bloque. Por lo tanto, es más
probable que los accesos subsiguientes acierten debido a la localidad espacial. Sin embargo,
un tamaño de bloque grande significa que una caché de tamaño fijo tendrá menos bloques.
Esto puede llevar a más conflictos, incrementando la tasa de fallos. Además, requiere más
tiempo traer el bloque de caché no encontrado después de un fallo, debido a que se trae de
memoria principal más de una palabra de datos. El tiempo requerido para cargar el bloque

15
fallido se denomina penalización por fallo. Si las palabras adyacentes del bloque no se acce-
den luego, se desperdicia el esfuerzo de traerlas. Sin embargo, la mayoría de los programas
reales se benefician de tamaños de bloque más grandes.

La Figura 8.12 muestra el hardware de una caché de correspondencia directa de C = 8 pala-


bras con un tamaño de bloque b = 4 palabras. La caché ahora sólo tiene B = C/b = 2 bloques.
Una caché de correspondencia directa sólo tiene un bloque en cada conjunto, por lo que esta
caché está organizada como dos conjuntos. Así, sólo log2 2 = 1 bit se usa para seleccionar el
conjunto. Ahora se necesita un multiplexor para seleccionar la palabra dentro del bloque. El
multiplexor es controlado por log2 4 = 2 bits de desplazamiento de bloque de la dirección. Los
27 bits más significativos de la dirección forman la etiqueta. Sólo se necesita una etiqueta
para todo el bloque, debido a que las palabras en el bloque están en direcciones consecutivas.

Figura 8.12 Caché de correspondencia directa con dos conjuntos y


un tamaño de bloque de cuatro palabras

Figura 8.13 Campos de la caché para la dirección 0x8000009C cuando se hace la


correspondencia a la caché de la Figura 8.12

La Figura 8.13 muestra los campos de la caché para la dirección 0x8000009C cuando se hace
corresponder en la caché de correspondencia directa de la Figura 8.12. Los bits de desplaza-
miento de byte siempre están en 0 para los accesos de palabras. Los siguientes log2 b = 2 bits
de desplazamiento de bloque indican la palabra dentro del bloque. Y el bit siguiente indica el
conjunto. Los 27 bits restantes son la etiqueta. Por lo tanto, la palabra 0x8000009C se corres-

16
ponde con el conjunto 1, palabra 3 en la caché. El método de usar tamaños de bloque más
grandes para explotar la localidad espacial también se aplica a las cachés asociativas.

Ejemplo 8.9 LOCALIDAD ESPACIAL CON UNA CACHÉ DE CORRESPONDENCIA


DIRECTA

Repetir el Ejemplo 8.6 para una caché de correspondencia directa de ocho palabras con un
tamaño de bloque de cuatro palabras.

Solución: La Figura 8.14 muestra el contenido de la caché después del primer acceso a me-
moria. En la primera iteración del bucle, la caché falla en el acceso a la dirección de memoria
0x4. Este acceso carga los datos de la dirección 0x0 hasta la 0xC en el bloque de la caché.
Todos los accesos subsiguientes (como se muestra para la dirección 0xC) aciertan en la caché.
Por consiguiente, la tasa de fallos es 1/15 = 6,67%.

Figura 8.14 Contenido de la caché con un tamaño de bloque (b) de cuatro palabras

Poniendo Todo Junto


Las cachés están organizadas como matrices de dos dimensiones. Las filas de llaman conjun-
tos y las columnas se llaman vías. Cada entrada en la matriz consta de un bloque de datos y
sus bits de etiqueta y válido asociados. Las cachés se caracterizan por

 capacidad C
 tamaño de bloque b (y cantidad de bloques, B = C/b)
 cantidad de bloques en un conjunto (N)

La Tabla 8.2 resume las diversas organizaciones de las cachés. Cada dirección de memoria se
corresponde con un solo conjunto, pero se puede almacenar en cualquiera de las vías.

La capacidad de la caché, la asociatividad, el tamaño del conjunto y el tamaño del bloque son
típicamente potencias de 2. Esto hace que los campos de la caché (etiqueta, conjunto y los bits
de desplazamiento de bloque) sean subconjuntos de los bits de dirección.

17
Tabla 8.2 Organizaciones de la caché

Organización Cantidad de Vías Cantidad de


(N) Conjuntos (S)
correspondencia
1 B
directa
asociativa de
1<N<B B/N
conjuntos

totalmente asociativa B 1

El incremento de la asociatividad, N, usualmente reduce la tasa de fallos causada por los con-
flictos. Pero una asociatividad mayor requiere más comparadores de etiqueta. El incremento
del tamaño del bloque, b, aprovecha la localidad espacial para reducir la tasa de fallos. Sin
embargo, disminuye la cantidad de conjuntos en una caché de tamaño fijo y por lo tanto puede
llevar a tener más conflictos. También incrementa la penalización por fallos.

8.3.3 ¿Qué Dato se Reemplaza?


En una caché de correspondencia directa, cada dirección se corresponde con un único bloque
y conjunto. Si cuando se debe cargar un dato un conjunto está lleno, se reemplaza el bloque en
ese conjunto con el dato nuevo. En las cachés asociativas de conjuntos y completamente aso-
ciativas, la caché debe elegir cuál bloque se debe desalojar cuando un conjunto de la caché
está lleno. El principio de localidad temporal sugiere que la mejor opción es desalojar el blo-
que que se usó menos recientemente, debido a que es menos probable que se lo use de nuevo
pronto. Así, la mayoría de las cachés asociativas tienen una política de reemplazo denominada
menos recientemente usado (least recently used o LRU).

En una caché asociativa de conjuntos de dos vías, un bit de uso, U, indica cuál vía dentro del
conjunto fue la menos recientemente usada. Cada vez que una de las vías se usa, se modifica
U para indicar la otra vía. Para las cachés asociativas de conjuntos con más de dos vías, seguir
la pista de la vía menos recientemente usada se vuelve complicado. Para simplificar el pro-
blema, a menudo se dividen las vías en dos grupos y U indica cuál grupo de vías fue menos
recientemente usado. Ante un reemplazo, el bloque nuevo reemplaza un bloque aleatorio den-
tro del grupo menos recientemente usado. Tal política se denomina pseudo LRU y en la prác-
tica es lo suficientemente buena.

Ejemplo 8.10 REEMPLAZO POR LRU


Muestre el contenido de una caché asociativa de conjuntos de dos vías y ocho palabras des-
pués de ejecutar el siguiente código. Asuma un reemplazo por LRU, un tamaño de bloque de
una palabra y una caché inicialmente vacía.

18
lw $t0, 0x04($0)
lw $t1, 0x24($0)
lw $t2, 0x54($0)

Solución: Las primeras dos instrucciones cargan los datos desde las direcciones de memoria
0x4 y 0x24 en el conjunto 1 de la caché, mostrado en la Figura 8.15(a). U = 0 indica que el
dato en la vía 0 fue el menos recientemente usado. El próximo acceso a memoria, a la direc-
ción 0x54, también se corresponde con el conjunto 1 y reemplaza el dato menos recientemen-
te usado que está en la vía 0, como se muestra en la Figura 8.15(b). El bit de uso, U, se pone
en 1 para indicar que el dato en la vía 1 fue el menos recientemente usado.

Figura 8.15 Caché asociativa de dos vías con reemplazo LRU

Políticas de escritura
Las secciones anteriores se enfocaron en las cargas de memoria. Los almacenamientos en
memoria, o escrituras, siguen un procedimiento similar a las cargas. Ante un almacenamiento
en memoria, el procesador verifica la caché. Si la caché falla, se trae el bloque de caché de
memoria principal a la caché, y luego se escribe la palabra apropiada en dicho bloque. Si se
acierta en la caché, simplemente se escribe la palabra en el bloque de caché.

Las cachés se clasifican en de escritura inmediata (write-through) o de escritura diferida


(write-back). En una caché de escritura inmediata, el dato escrito en un bloque de caché se
escribe simultáneamente en memoria principal. En una caché de escritura diferida, se asocia
un bit de modificado (o dirty bit) (D) con cada bloque de la caché. D vale 1 cuando se ha es-
crito en el bloque de cache y 0 en caso contrario. Los bloques de caché modificados se rees-
criben en memoria principal sólo cuando se los desaloja de la caché. Una caché de escritura
inmediata no requiere del bit de modificado pero usualmente requiere más escrituras a memo-

19
ria principal que una caché de escritura diferida. Las cachés modernas usualmente son de es-
critura diferida, debido a que el tiempo de acceso a memoria principal es tan largo.

Ejemplo 8.12 ESCRITURA INMEDIATA VERSUS ESCRITURA DIFERIDA


Suponga que una caché tiene un tamaño de bloque de cuatro palabras. ¿Cuántos accesos a
memoria principal se requieren para el siguiente código cuando se usa cada política de escri-
tura: inmediata o diferida?

sw $t0, 0x0($0)
sw $t0, 0xC($0)
sw $t0, 0x8($0)
sw $t0, 0x4($0)

Solución: Las cuatro instrucciones de almacenamiento escriben en el mismo bloque de ca-


ché. Con una caché de escritura inmediata, cada instrucción de almacenamiento escribe una
palabra en memoria principal, requiriendo cuatro escrituras en memoria principal. Una políti-
ca de escritura diferida requiere sólo un acceso a memoria principal, cuando se desaloja el
bloque de caché modificado.

20