P3: Caché en la Pico - myTeachingURJC/Arq-computadores-01 GitHub Wiki
Sesión 3: Memoria caché
En esta práctica pondremos en práctica los conceptos estudiados de memoria caché.
IMPORTANTE: Para realizar esta práctica, es necesario que hayas leído en casa antes la sesión S4 hasta caché de varios niveles (no incluido), ábrela en otra pestaña para consultar conceptos que no recuerdes.
Solo necesitaremos la RPi y el cable USB, guarda el resto de elementos dentro de la caja.
1. Efecto de la memoria caché en la lectura de instrucciones
Como hemos visto en la S4, la memoria caché hace que la lectura de la memoria sea más rápida.
Vamos a utilizar un programa de prueba, en el que medimos únicamente el número de ciclos que tarda en ejecutarse una instrucción addi:
.include "compile/gpio.s"
.global asm_main #-- Punto de entrada
.eqv MTIME_CTRL, 0xD00001A4 #-- Timer Control
.eqv MTIME, 0xD00001B0 #-- Temporizador del RISCV
.eqv GPIO_BASE, 0xD0000001
.eqv GPIO_IN_OFFSET, 0x5
.eqv GPIO_OUT_OFFSET, 0x10
.data
msg: .string "\n\n N ciclos: "
.text
# -- Punto de entrada
asm_main:
#-- Inicializar GPIOs
jal init
#-- Arrancar temporizador
li t0, MTIME_CTRL
li t1, 0x3
sw t1, 0(t0)
loop:
li s1, 0
#-- Comenzar medición
li t5, MTIME
lw s4, 0(t5)
#-- Código a medir
addi s1, s1, 1
#-- Terminar la medición
lw s5, 0(t5)
sub s4, s5, s4
addi s4, s4, -1
#-- Imprimir resultado
la a0, msg
jal print
mv a0, s4
jal print_unsigned_int
#-- Espera de medio segundo
li a0, 500
jal sleep_ms
#-- Bucle infinito
j loop
Copia y pega este código en un archivo que se llame p3_a.s, ensámblalo y cárgalo en la RPi
Abre el monitor serie para ver lo que imprime la RPi. Recuerda activar la opción de reconexión automática.
Para ver los ciclos que se imprimen desde el principio, sin cerrar el monitor, desconecta y conecta el usb de la RPi.
Observa los ciclos que indica que tarda en ejecutar addi.
Pregunta 1: ¿Hay alguna diferencia entre los ciclos en la primera ejecución y las siguientes?¿A qué puede deberse?
2. Caché en la lectura de datos
Ahora vamos a medir cuánto tarda en ejecutarse una instrucción que accede a memoria, en concreto lw.
Utilizaremos este código en el que se leen todos los números de un array de 20 números y se mide el número de ciclos que se tarda en leer el dato con lw.
El programa imprime el número leído, y después el número de ciclos que ha tardado. Después de leer los 20 números, termina.
.include "compile/gpio.s"
.global asm_main #-- Punto de entrada
.eqv MTIME_CTRL, 0xD00001A4 #-- Timer Control
.eqv MTIME, 0xD00001B0 #-- Temporizador del RISCV
.eqv GPIO_BASE, 0xD0000001
.eqv GPIO_IN_OFFSET, 0x5
.eqv GPIO_OUT_OFFSET, 0x10
.section .rodata
cad:
.word 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
.word 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
.data
msg: .string "\n N ciclos: "
msg2: .string "\n\n Numero: "
.text
# -- Punto de entrada
asm_main:
#-- Inicializar GPIOs
jal init
#-- Arrancar temporizador
li t0, MTIME_CTRL
li t1, 0x3
sw t1, 0(t0)
la s0, cad
loop:
#-- Comenzar medición
li t5, MTIME
lw s4, 0(t5)
#-- Código a medir
lw s1, 0(s0)
#-- Terminar la medición
lw s5, 0(t5)
sub s4, s5, s4
addi s4, s4, -1
#-- Imprimir el número
la a0, msg2
jal print
mv a0, s1
jal print_unsigned_int
#-- Imprimir el número de ciclos
la a0, msg
jal print
mv a0, s4
jal print_unsigned_int
#-- Espera de medio segundo
li a0, 500
jal sleep_ms
#-- Incremento de puntero
addi s0, s0, 4
#-- Si no hemos llegado al final repetimos
li t2, 76
blt s0, t2, loop
fin:
j fin
Copia el código en el archivo p3_b.s, ensámblalo y pruébalo.
¿Observas alguna diferencia en el número de ciclos que se tarda en leer cada número?¿A qué se debe?
Pregunta 2: Indica cuánto tarda en leer los datos que tiene en caché (aciertos), y cuánto los que no tiene en caché (fallos). Para simplificar asume que todo el tiempo de ciclo se consume en leer de memoria y que la frecuencia del procesador es de 150MHz
Pregunta 3: obtén para esas 20 lecturas de memoria, la tasa de aciertos, la tasa de fallos y el tiempo medio de lectura.
Pregunta 4: Determinar el tamaño del bloque de caché basado en lo que observas (en bytes)
3. Aprovechando la caché
En el ejemplo anterior, a pesar de que cada dato que leíamos era nuevo, al guardarse en caché por bloques, vemos cómo se mejora el rendimiento y en muchos ciclos se leía el dato de caché reduciendo el tiempo medi de lectura.
Ahora, vamos a ver cómo se comporta la caché si ya ha leído alguna vez los datos de memoria. Para ello, modifica el código anterior, y haz que, cuando llegue al número 20, en lugar de terminar en un bucle infinito, se resetee el puntero y se vuelvan a leer otra vez. El programa debe leer en bucle los 20 números de memoria.
Observa cuánto tarda en leer de memoria los datos a partir de la segunda iteración del bucle (la segunda vez que lee el array)
Pregunta 5: ¿Cuál es la tasa de fallos y el tiempo medio de lectura a partir de la segunda iteración?
4. Clase teórica caché, políticas de reemplazo, etc.
Explicación o lectura del resto de la sesión S4, a partir de caché de varios niveles
Autores
- Miguel Ángel de Miguel
- Juan González-Gómez (Obijuan)
Enlaces
Licencia
