• No se han encontrado resultados

Sistemas de memoria 6.1 Suponga una memoria principal de 8192 bytes y una memoria cache

In document Sistemas Computacionales (página 70-85)

de 64 bytes, organizada como 16 líneas de 4 bytes cada una, dividida en dos conjuntos.

El contenido de la cache es como se muestra en la siguiente tabla, donde la primea columna es el número de línea, V es el bit de validez, y B0a

B3son los bytes 0 a 3, respectivamente.

Cache asociativa de 2 conjuntos

Tag V B0 B1 B2 B3 Tag V B0 B1 B2 B3 0 09 1 86 30 3F 10 00 0 99 04 03 48 1 45 1 60 4F E0 23 38 1 00 BC 0B 37 2 EB 0 2F 81 FD 09 0B 0 8F e2 05 BD 3 06 0 3D 94 9B F7 32 1 12 08 7B AD 4 C7 1 06 78 07 C5 05 1 40 67 C2 3B 5 71 1 0B DE 18 4B 6E 0 B0 39 D3 F7 6 91 1 A0 B7 26 2D F0 0 0C 71 40 10 7 46 0 B1 0A 32 0F DE 1 12 C0 88 37

a) Indique en un diagrama los bits de la dirección física correspon-

dientes a 1) el tag 2) el índice

3) el número del byte en la línea

b) El procesador genera la dirección 0x0E34. Indique la línea de la

cache accesada y el byte accedido. Indique además si el acceso ge- nera un fallo en cache.

6.2 Ud. ha comprado un nuevo computador, y estudios de desempeño en éste le indican que:

95% de los accesos a memoria son atendidos por la memoria ca- che.

Cada bloque de memoria cache es de 2 palabras, y el bloque com- pleto es transferido desde memoria RAM a la memoria cache en caso de una falta de cache.

El procesador genera, en promedio, 109 direcciones de memoria

por segundo.

25% de estas direcciones son escrituras a memoria.

Suponga que el sistema de memoria soporta 109 accesos por se-

gundo, pero el bus de interconexión sólo soporta un acceso a la vez (no puede haber 2 lecturas o escrituras a memoria en forma simultánea).

Suponga que, en promedio, el 30% de los bloques en la cache han sido modificados.

Calcule el tiempo de acceso promedio a memoria y el porcentaje de utilización del bus de interconexión para los siguientes casos:

a) La memoria cache es Write-Through b) La memoria cache es Write-Back

6.3 Suponga que la ejecución de un programa en un computador con un sistema de memoria ideal muestra un CPI de 1.5. El sistema de memo- ria real del computador tiene una latencia de 40 ciclos, después de los cuales la memoria RAM es capaz de entregar 4 bytes en cada ciclo de reloj. Suponga además que hay 32 bytes en una línea de memoria ca- che, que el 20% de la instrucciones son instrucciones de transferencias de datos, y que el 50% de estas instrucciones son escrituras a bloques de memoria modificados. Se sabe que este computador puede utilizarse con

Una memoria cache unificada de 16 KiB con asociatividad directa, que utiliza Write-Back y tiene una tasa de fallas de 2.0%.

Una memoria cache unificada de 16 KiB con asociatividad de dos vías, que utiliza Write-Back y tiene una tasa de fallas de 2.2%. Una memoria cache unificada de 32 KiB con asociatividad directa, que utiliza Write-Back y tiene una tasa de fallas de 2.9%.

Calcule para todos los casos el CPI efectivo del sistema.

6.4 Suponga que tiene el siguiente código C que se ejecutará en un siste- ma con una memoria cache directamente asociativa de 1024 bytes de tamaño, con 16 bytes por línea.

struct posicion { int x;

int y; };

struct posicion malla[16][16]; int xTotal = 0; yTotal = 0; int i, j; for (i = 0; i < 16; i++) { for (j = 0; j < 16; j++) { xTotal += malla[i][j].x; } } for (i = 0; i < 16; i++) { for (j = 0; j < 16; j++) { yTotal += malla[i][j].y; } }

Suponga además que:

Un entero int ocupa 4 bytes. La cache está inicialmente vacía.

La matriz malla se almacena en memoria a partir de la posición 0x00.

Las variables i, j, xTotal y yTotal se almacenan en los registros del procesador.

Entonces,

a) Calcule la tasa de fallos de la memoria cache b) Repita lo anterior para el siguiente lazo

for (i = 0; i < 16; i++) { for (j = 0; j < 16; j++) { xTotal += malla[i][j].x; yTotal += malla[i][j].y; } }

c) Repita el punto anterior, pero ahora suponiendo una memoria ca-

che del doble del tamaño

d) Repita ahora los dos puntos anteriores para el siguiente lazo

for (i = 0; i < 16; i++) { for (j = 0; j < 16; j++) { xTotal += malla[j][i].x; yTotal += malla[j][i].y; } } Solución

La matriz malla contiene 256 elementos de tipo posicion, cada uno de ellos de 2 enteros, ocupando 8 bytes. Entonces, la matriz ocupa 2048 bytes, así que no cabe completamente en la memoria cache. Además, una línea de cache contiene 16 bytes o 2 elementos de la matriz malla. Por ello, no hay aciertos en cache por reutilización de datos y sólo pue- de haber aciertos en accesos a datos que hayan sido precargados en la cache.

a) El primer ciclo anidado accede primero a todos los miembros x

y luego a todos los miembros y de las estructuras posición de la matriz malla. El primer acceso a un miembro x transfiere 2 es- tructuras posicion a la memoria cache, pero sólo la escritura al miembro x del segundo elemento transferido serán aciertos en la cache. Esta situación se repite para los accesos a los miembros y de la matriz. Así, la tasa de fallos es 50%.

b) En este caso, se accede a los elementos de la matriz por filas, y a

ambos miembros de una estructura posición en forma secuencial. El acceso al primer miembro x será un fallo en la cache, pero los tres accesos siguientes serán aciertos en la cache, así que la tasa de fallos será 25%.

c) La tasa de fallo no se ve afectada si el tamaño de la memoria se

d) En este caso, se accede a los elementos de la matriz por columnas,

por lo que el acceso al miembro x será un fallo de la cache, pero el acceso al miembro y del mismo elemento será un acierto. Por ello, la tasa de fallos será de 50%. Si la memoria cache se duplica, entonces la tasa de fallos disminuye a 25%.

6.5 Sea una memoria cache directa de 64 KiB con bloques de 16 bytes, que utiliza buffers de escritura y una política de escritura Write-allocate. Su- ponga además que se está utilizando un procesador de 32 bits, que sizeof(int) = 4, que la memoria cache inicialmente está vacía, que las variables locales utilizan los registros de la CPU, que los cálculos de índices tienen lugar exclusivamente en los registros de la CPU, que la matriz fuente comienza en la dirección de memoria 0x00, y que la matriz destino comienza inmediatamente después.

Entonces, para el siguiente código matricial:

void copiaMatriz(int destino[FILAS][COLS], int fuente[FILAS][COLS]) { int i, j;

for (i = 0; i < FILAS; i++) { for (j = 0; j < COLS; j++) {

destino[i][j] = fuente[i][j]; }

} }

Indique las tasas de acierto a la memoria cache si

a) FILAS = 128 y COLS = 128 b) FILAS = 128 y COLS = 192 c) FILAS = 128 y COLS = 256

Finalmente, un compañero suyo le dice que podría mejorar las tasas de aciertos anteriores realizando la copia byte-a-byte en vez de usar enteros. Tiene razón su compañero? Cuáles son las desventajas de su propuesta?

Solución

Dados los parámetros indicados, se sabe que la memoria cache contiene 212= 4096 líneas de 16 bytes cada una.

El código a ejecutar no posee localidad temporal en las matrices fuente y destino, por lo que sólo cabe estudiar si existe localidad espacial gracias a las transferencias de bloques entre RAM y cache.

Para facilitar la comprensión del problema, la siguiente tabla muestra las direcciones iniciales y finales de las matrices fuente y destino para cada caso. Cabe destacar que el grupo de 3 dígitos hexadecimales en negrita en el centro de la dirección corresponde al índice de la dirección en la cache.

Filas Cols. Dir. matriz fuente Dir. matriz destino 128 128 0x00000000 - 0x0000FFFF 0x00010000 - 0x0001FFFF 128 192 0x00000000 - 0x00017FFF 0x00018000 - 0x0002FFFF 128 256 0x00000000 - 0x0001FFFF 0x00020000 - 0x0003FFFF

a) En el primer caso, las matrices fuente y destino tienen 128 ×

128 × 4 = 64 KiB cada una. Como ambas matrices están contiguas en memoria, entonces la dirección del elemento fuente[0][0] tiene exactamente el mismo índice que la dirección del elemen- to destino[0][0]. En otras palabras, la lectura de fuente[0][0] transfiere una línea de 4 enteros, fuente[0][0] a fuente[0][3], desde RAM a la línea 0 de la memoria cache. Pero, la escritura de destino[0][0]transfiere la línea de 4 enteros, destino[0][0] a destino[0][3], desde RAM a la línea 0 de la memoria cache, la cual necesariamente reemplaza a los 4 enteros de la matriz fuente. A continuación, se lee fuente[0][1] y se escribe destino[0][1], repitiéndose el proceso. Por ello, la tasa de aciertos es 0%.

b) En el segundo caso, las matrices fuente y destino tienen 128 ×

192 × 4 = 96 KiB cada una. Los índices en la cache de los primeros elementos de ambas matrices son diferentes, por lo que es posible tener las primeras líneas de ambas matrices residentes en memo- ria cache al mismo tiempo, y así aprovechar la localidad espacial inherente a usar bloques de 4 enteros. En este caso, la tasa de acier- tos es34 = 75%.

c) En este caso, las matrices fuente y destino tienen 128 × 256 × 4 =

128 KiB cada una, y se repite la situación del primer caso: la tasa de aciertos es 0%.

Finalmente, si se realizara la copia de matrices byte-a-byte en vez de usar enteros, las tasas de acierto de los casos a) yc) no cambiarían. En cambio, en el caso b) la tasa de aciertos sería de 1516 = 93.75%. Sin em- bargo, se realizarían 16 operaciones de lectura y escritura por bloque transferido en vez de 4, lo que aumenta considerablemente el costo de realizar la copia de las matrices.

6.6 Considere el siguiente código C, que calcula la traspuesta de una matriz typedef int matriz[2][2];

void traspuesta(matriz destino, matriz fuente) { int i, j; for (i = 0; i < 2; i++) { for (j = 0; j < 2; j++) { destino[j][i] = fuente[i][j]; } } }

Suponga que este código se ejecuta en una máquina de 32 bits con las siguientes características:

La matriz destino comienza en la dirección de memoria 0 y la matriz fuente comienza en la dirección de memoria 0x0010. El sistema posee una cache de datos L1 de 16 bytes de tamaño, asociatividad directa, una política de escrituras Write-Through y líneas de 8 bytes.

Esta cache está inicialmente vacía.

Los únicos accesos a memoria son las lecturas y escrituras a las matrices destino y fuente.

Entonces:

a) Para cada elemento de las matrices destino y fuente, indique si

su acceso fue una falla o un acierto en cache.

b) Calcule la tasa de aciertos de la matriz.

6.7 Ud. está escribiendo un nuevo juego 3D para celulares que le darán fama y fortuna, y hoy debe escribir una función que limpie la pantalla antes de dibujar la siguiente imagen. La pantalla tiene 480 líneas de 640 pixeles cada una. El procesador que Ud. está utilizando tiene una cache directa de 64 KiB con líneas de 4 bytes. Las estructuras de datos básicas que Ud. está usando son:

struct pixel { char r; char g; char b; char a; };

struct pixel buffer[480][640]; int i, j;

char *cptr; int *iptr;

Suponga que sizeof(char) = 1, sizeof(int) = 4, que buffer está almacenado a partir de la dirección de memoria 0x0000, que la cache está inicialmente vacía y que las variables i, j, cptr y iptr están al- macenadas en los registros del procesador, de manera que los únicos accesos a memoria son a direcciones dentro de buffer.

a) Ud. primero escribe el siguiente código para limpiar la pantalla.

Calcule la tasa de aciertos de la cache. for (j = 0; j < 640; j++) { for (i = 0; i < 480; i++) { buffer[i][j].r = 0; buffer[i][j].g = 0; buffer[i][j].b = 0; buffer[i][j].a = 0; } }

b) Luego, Ud. escribe el siguiente código para limpiar la pantalla.

Calcule la tasa de aciertos de la cache. char *cptr;

cptr = (char *) buffer;

*cptr = 0; }

c) Finalmente, Ud. escribe el siguiente código para limpiar la panta-

lla. Calcule la tasa de aciertos de la cache. int *iptr;

iptr = (int *) buffer;

for (; iptr < buffer + 640*480; iptr++) { *iptr = 0;

}

d) Cuál código usará Ud.?

Solución

En este problema, el tamaño de la pantalla determina la cantidad de memoria necesaria para desplegar una imagen como 640 ∗ 480 ∗ 4 = 1228800 bytes, donde cada pixel se almacena en 4 bytes. Para limpiar la pantalla, cada pixel será accedido sólo una vez, así que los únicos aciertos posibles son en accesos a datos precargados en una línea de la cache, de tamaño 4 bytes.

a) En este caso, acceder al primer elemento r de la estructura de da-

tos pixel es un fallo en la cache y provoca la transferencia de la estructura completa desde memoria a la cache. Luego, los accesos a los otros tres elementos de la estructura son aciertos en la cache. Este patrón se repite para cada pixel accedido, así que la tasa de aciertos de la cache es 75%.

b) En este caso, se accede secuencialmente a cada elemento de la me-

moria por byte. Nuevamente, no hay reutilización de datos excep- to en la línea de cache. En este caso, el acceso al primer byte de la línea es un fallo en la cache, pero los accesos a los tres bytes si- guientes son aciertos en la cache. Por ello, la tasa de aciertos es de 75%.

c) En este caso, se accede secuencialmente a cada elemento de la me-

moria en unidades de 4 bytes, que es el tamaño de la línea de ca- che. No hay reutilización de líneas de cache, así que todos los acce- sos a memoria son fallos en la cache, por lo que la tasa de aciertos de la cache es de 0%.

d) La principal componente del tiempo de ejecución de estos códigos

memoria cache. Aun cuando las dos primeras alternativas tienen tasas de acierto mayores, los tres códigos involucran igual canti- dad y frecuencia de transferencias entre memoria principal y me- moria cache. La última opción ejecuta menos instrucciones en un lazo más compacto. Si suponemos que el procesador puede escri- bir 4 bytes a memoria cache en un mismo ciclo de bus, la última alternativa bien puede ser la más rápida.

6.8 La siguiente tabla muestra los parámetros de diferentes caches para un procesador de 32 bits. En dicha tabla, C es el número de bytes de datos de la cache, B es el tamaño del bloque de cache en bytes, y E es el número de bloques por conjunto. Calcule S: el numero de vías de la cache, t: el numero de bits en el tag, i: el número de bits usados como índice, b: el número de bits usados como desplazamiento en el bloque, y T: el número total de bits en la cache, incluyendo datos, tag, bit de validez y de modificación. C B E S t i b T 1024 4 4 1024 4 256 2048 8 1 2048 8 128 4096 32 1 8192 32 4 Solución

La tabla se llena usando las fórmulas S = C

BE, b = log2(B), i = log2(S), t = 32− b − i, y T = 8C +CB(t + 2). C B E S t i b T 1024 4 4 64 24 6 2 8192 + 6656 = 14848 1024 4 256 1 30 0 2 8192 + 8192 = 16384 2048 8 1 256 21 8 3 16384 + 5888 = 22272 2048 8 128 2 28 1 3 16384 + 7680 = 24064 4096 32 1 128 20 7 5 32768 + 2816 = 35584 8192 32 4 64 21 6 5 65536 + 5888 = 71424

6.9 Se le ha pedido escribir el código para dirimir la elección de alcalde en la comuna de San Pablo de la Paz, donde hay 7 candidatos a la alcal- día. Ud. desarrolla entonces un programa en C y busca optimizar su desempeño. El software que Ud. desarrolle se ejecutará en un procesa- dor de 32 bits que posee una memoria cache directa de 1024 bytes, con bloques de 64 bytes. Suponga además que inicialmente esta cache esta vacía.

En su código, Ud. utiliza la siguiente estructura de datos struct Voto {

int candidatos[7]; int valido; };

struct Voto matrizVotos[16][16];

// Estas variables se almacenan en registros de la CPU register int i, j, k;

Entonces, Ud. escribe el siguiente código C para inicializar las estruc- turas de datos a utilizar.

for (i = 0; i < 16; ++i) { for (j = 0; j < 16; ++j) { matrizVotos[i][j].valido = 0; } } for (i = 0; i < 16; ++i) { for (j = 0; j < 16; ++j) { for (k = 0; k < 7; ++k) { matrizVotos[i][j].candidatos[k] = 0; } } }

Su colega escribe el siguiente código C para realizar la misma función. for (i = 0; i < 16; i++) { for (j = 0; j < 16; j++) { for (k = 0; k < 7; k++) { matrizVotos[i][j].candidatos[k] = 0; } matrizVotos[i][j].valido = 0; } }

Su jefe dice que dará un bono de producción al programador cuyo códi- go tenga el menor número de faltas de cache. Suponiendo que el área de datos de su programa comienza en la posición de memoria 0x4000, que un dato int ocupa 4 bytes, y que las variables i, j y k están en registros de la CPU, quién de Uds. dos recibe el bono? Justifique su respuesta calculando la tasa de aciertos en cada caso.

Solución

Dado que el bloque es de 64 bytes y cada estructura Voto ocupa 32 by- tes, entonces un bloque de cache almacena 2 estructuras Voto. En ese caso, acceder a cualquier miembro del dato matrizVotos[0][0] trans- fiere las estructuras matrizVotos[0][0] y matrizVotos[0][1] a me- moria cache.

En el primer código, el primer conjunto de ciclos realiza 256 accesos a memoria, de los cuales la mitad son fallas en cache. El segundo con- junto de ciclos realiza 1792 accesos a memoria, de los cuales 1 de cada 14 es una falla en cache, y el resto son aciertos. Entonces, la tasa de aciertos es128+16642048 = 87.5%.

En cambio, el segundo código también realiza 2048 accesos a memoria, de los cuales 1920 corresponden a aciertos en la cache, lo que da una tasa de aciertos de 19202048= 93.75%. Por ello, su colega recibe el bono. 6.10 Suponga que el programa palindromo del ejercicio 4.5 se ejecuta utili-

zando una cache directa unificada de 64 bytes de tamaño, con bloques de 4 bytes cada uno. Calcule la tasa de aciertos de la cache al ejecutar la función anterior con los argumentos radar y el largo 5, donde la ristra a procesar está residente en memoria a partir de la posición de memo- ria 0x200. Recuerde que la memoria cache es accedida por bytes por la CPU.

Solución

Analizaremos la ejecución de las instrucciones de la función con los argumentos radar y el largo 5. Por simplicidad y falta de información, no consideraremos el efecto de la pila.

Inicialmente, se ejecutan las instrucciones 1 a 15, después se ejecutan las instrucciones 8 a 15, luego nuevamente las instrucciones 8 a 14, luego las instrucciones 16, 17 y finalmente las instrucciones 19 a 21. La ejecución de estas 27 instrucciones involucra leer 74 bytes desde memoria RAM. A su vez, estos bytes de memoria están almacenados en 13 líneas de 4 bytes que serán transferidas consecutivamente a los

bloques 1 a 13 de la memoria cache. Como la cache inicialmente está vacía, estas 13 transferencias producen 13 fallos en cache. Entonces, la ejecución del código produce 13 fallos y 61 aciertos en cache.

Por otro lado, los 5 bytes del argumento se almacenan a partir de la posición de memoria 0x200. Esto corresponde a 2 líneas de memoria, las que se transferirán a los bloques 0 y 1 de la memoria cache. Afortu- nadamente, no hay interferencia en el uso del bloque 1 de la memoria cache por parte del código. Durante la ejecución, se accede a los bytes 0x200, 0x201, 0x203 y 0x204 una vez, y al byte 0x202 dos veces. Estos accesos generan 2 fallos y 4 aciertos en cache.

Entonces, podemos decir que, en total, se realizan 80 accesos a cache, de los cuales 15 son fallos y 65 son aciertos, para una tasa de aciertos de 81.25%.

6.11 Un cierto sistema computacional tiene la siguiente jerarquía de memo- ria:

Nivel Tamaño Asociatividad Tiempo de acceso Tasa de aciertos

L1 32 KiB 8 vías 1 ciclo 90%

L2 256 KiB 8 vías 5 ciclos 95%

L3 8 MiB 16 vías 40 ciclos 98%

RAM 8 GiB 120 ciclos 100%

Calcule el tiempo de acceso promedio TProm. Solución

El tiempo de acceso promedio TPromse calcula como se muestra a con- tinuación.

TProm= 0.9 ∗ 1 + 0.1 ∗ (0.95 ∗ 5 + 0.05 ∗ (0.98 ∗ 40 + 0.02 ∗ 120)) = 1.583 6.12 Intel está diseñando una nueva CPU y quieren consultarle su opinión.

Las alternativas en consideración son: una cache de 32 KiB de arqui- tectura Harvard dividida en 16 KiB para instrucciones y 16 KiB para datos, o una cache unificada de 32 KiB. Mediciones realizadas entregan las siguientes tasas de fallo en función del tamaño de la cache:

Tamaño Cache de inst. Cache de datos Cache unificada

16 KiB 0.64% 6.47% 2.87%

32 KiB 0.39% 4.82% 1.99%

Además, se sabe que:

El 75% de los accesos a memoria son lecturas de instrucciones El tiempo de acceso a la cache es de 1 ciclo de reloj

El tiempo de acceso a RAM es de 50 ciclos de reloj

La memoria cache es de tipo write-through, con buffers de escritura La memoria cache de arquitectura Harvard tiene dos puertos de acceso, lo que permite leer una instrucción y un dato en un ciclo La memoria cache unificada tiene sólo un puerto de acceso, por lo que un acceso de lectura ó escritura de datos requiere de 1 ciclo de reloj adicional.

Dado lo anterior,

a) calcule la tasa de fallos para la cache de arquitectura Harvard, b) calcule el tiempo de acceso promedio para ambas arquitecturas de

cache.

Cuál solución recomienda Ud.? Solución

El que la memoria cache sea de tipo write-through con buffers de escritu- ra implica que, desde el punto de vista de la CPU, las escrituras a cache demoran un ciclo, ya que la transferencia de datos entre la cache y la memoria RAM ocurre bajo el control del buffer.

a) La tasa de fallos para la cache de arquitectura Harvard se puede

calcular como:

(75% ∗ 0.64%) + (25% ∗ 6.47%) = 2.0975%

b) El tiempo de acceso promedio de la cache de arquitectura Harvard

es: 3

4 ∗((1−0.64%)+0.64%∗50)+ 1

En cambio, el tiempo de acceso promedio de la cache unificada es: 3

4 ∗((1−1.99%)+1.99%∗50)+ 1

4 ∗((1−1.99%)+1+1.99%∗50) = 2.225 Por lo tanto, la cache de arquitectura Harvard tiene un desempeño superior.

Planificación de procesos

In document Sistemas Computacionales (página 70-85)