Document

Anuncio
ESTRUCTURA Y TECNOLOGÍA DE COMPUTADORES
I.T.I. Gestión, I.T.I. Sistemas e I. Superior, Grupos I y II
Segundo Parcial – 15 de marzo de 2005
SOLUCIONES PROBLEMAS:
1. (3.5 puntos) Dado el siguiente procedimiento escrito en código MIPS:
Proc:
loop:
fin:
move
xor
bge
sll
add
lw
add
addi
j
jr
$t0,$0
$v0, $v0, $v0
$t0, $a1, fin
$t1, $t0, 2
$t2, $a0, $t1
$t2, 0($t2)
$v0, $v0, $t2
$t0, $t0, 1
loop
$ra
a) (0.25 puntos) Describir en castellano, de forma muy breve y concisa (una única frase bastaría) qué utilidad tiene esta rutina, es decir, qué
valor devuelve en función de los parámetros $a0 (que contiene la dirección de memoria de un array de enteros de 32 bits) y $a1 (que indica el
número de elementos del array).
b) (0.75 puntos) Escribir el código máquina MIPS mínimo a que daría lugar el programa dado que éste se sitúa a partir de la dirección de
memoria 0x0400 0010 (ver Notas 1 y 2).
c) (0.5 puntos) El equipo de diseño de MIPS ha incluido una nueva instrucción en el ISA, aw $x, Cte($y) —accumulate word—. La nueva
instrucción actúa de igual forma que la instrucción lw salvo que en lugar de sobrescribir el contenido del registro destino ($x) con el valor leído
de memoria, aw suma éste al contenido de $x (es decir, acumula el valor leído de memoria en $x). Reescribir la rutina anterior haciendo uso de
la nueva instrucción aw.
d) (1 punto) Suponer que las unidades funcionales del camino de datos monociclo introducen los siguientes retardos: Memorias (instrucciones y
datos)→2 ns, ALU y Sumadores→2ns y Banco de Registros (lectura y escritura)→1 ns. Dado que se llama a Proc con los siguientes
parámetros: $a0→dirección de memoria del array {0,1,2,3,-3,-2,-1,0} y $a1→8 y que la instrucción aw se implementa en el procesador
monociclo igual que lw pero añadiendo un sumador entre la salida de la memoria de datos y la entrada de escribir dato del banco de registros,
¿recomendarías al equipo de diseño incluir la instrucción en el procesador monociclo?.
e) (1 punto) ¿Y en el procesador multiciclo?. Supón los mismos valores utilizados en el apartado anterior y que la instrucción aw se implementa
utilizando dos veces la ALU (además de las que se usa en los dos primeros ciclos), una para calcular la dirección de memoria efectiva y la
otra para acumular el valor leído de memoria en el registro destino (ver Nota 3)
Notas.1.
Invente los códigos de operación y función de las instrucciones. Construir una tabla como la que se muestra a continuación:
0x0400 0010
011...
011...
100...
...
addi $11, ...
Formato X
Dir. Siguiente
...
Direcciones
(hexadecimal)
2.
3.
Campos de las instrucciones (binarios o hexadecimal).
Cada una con su formato divido en campos.
1 instrucción por fila (ensamblador),
no pseudoinstrucciones.
Los registros $a0 y $a1 se corresponden con el $4 y el $5 respectivamente, $v0 se corresponde con el $2, $ra con el $31, mientras que $t0, $t1 y $t2 son los
registros $8, $9 y $10 respectivamente.
Para el apartado e) suponer que las instrucciones aritmético-lógicas inmediatas (addi, andi, lui, ...) y de desplazamiento duran 4 ciclos. Para el resto de
instrucciones asumir los retardos vistos en clase para el camino de datos multiciclo.
Solución
a)
El procedimiento devuelve el resultado de la suma de los n primeros enteros de un array de enteros cuya dirección de comienzo se pasa
como parámetro ($a0). El número n es el segundo parámetro que se pasa al procedimiento ($a1).
b)
b.1) Identificación de pseudoinstrucciones y obtención de las instrucciones MIPS equivalentes:
move $t0, $0
bge $t0, $a1, fin
→
→
add $8, $0, $0
slt $1, $8, $5
beq $1, $0, fin
b.2) El código máquina resultante es el siguiente:
Dirección
0x04000010
0x04000014
0x04000018
0x0400001C
0x04000020
0x04000024
0x04000028
0x0400002C
0x04000030
0x04000034
0x04000038
c)
loop:
fin:
Inst MIPS
add $8, $0, $0
xor $2, $2, $2
slt $1, $8, $5
beq $1,$0,fin
sll $9, $8, 2
add $10,$4,$9
lw $10,0($10)
add $2,$2,$10
addi $8,$8,1
j loop
jr $31
Instrucción Máquina
0
$0 $0
$8
0 add
0
$2 $2
$2
0 xor
0
$8 $5
$1
0
slt
beq $1 $0
0x0006
0
0
$8
$9
2
sll
0
$4 $9 $10 0 add
lw $10 $10
0x0000
0
$2 $10 $2
0
add
addi $8 $8
0x0001
j
0x1000006 (26 bits)
jr $31 $0 $0
0
0
Formato
Tipo R
Tipo R
Tipo R
Tipo I
Tipo R
Tipo R
Tipo I
Tipo R
Tipo I
Tipo J
Tipo R
Después de utilizar la instrucción aw el código quedaría como sigue:
Proc:
loop:
fin:
add
xor
slt
beq
sll
add
aw
addi
j
jr
$t0,$0,$0
$v0, $v0, $v0
$at, $t0, $a1
$at, $0, fin
$t1, $t0, 2
$t2, $a0, $t1
$v0, 0($t2)
$t0, $t0, 1
loop
$ra
# Se sustituye el lw y add por la instrucción aw.
d) Para implementar la instrucción en el procesador monociclo nos dicen que se ha añadido un sumador entre la salida de la
memoria de datos y la entrada escribir dato del banco de registros. Este sumador será el encargado de sumar el valor leído de
memoria al contenido del registro destino (para el código anterior $v0, que es el registro en el que se van acumulando todos
los valores leídos de memoria). El resto de pasos de la instrucción aw son los mismos que para lw. De esta forma, los pasos
necesarios para ejecutar aw son: 1. Buscar la instrucción e incrementar el PC en 4, 2. Leer los registros $t2 y $v0 y
decodificar la instrucción, 3. Calcular con la ALU la dirección de memoria a leer, 4. Leer la posición de memoria, 5. Sumar
el valor leído de memoria al contenido de $v0 y 6. Almacenar el resultado de la suma en $v0.
A partir de los retardos de las unidades funcionales que se nos dan, una instrucción aw tardaría: 2 ns. (Memoria de
instrucciones) + 1 ns. (BR) + 2 ns. (ALU) + 2 ns. (Memoria de datos) + 2 ns. (Sumador extra) + 1 ns. (BR) = 10 ns. Puesto
que la duración de la instrucción de carga es de 8 ns., esta instrucción deja de ser la “más lenta” y por tanto la que determina
la duración del ciclo de reloj en el procesador monociclo. Cuando incluimos la instrucción aw en el procesador monociclo la
duración del ciclo de reloj se incrementa 2 ns. con respecto al procesador monociclo sin esta instrucción.
El determinar si merece la pena incluir la nueva instrucción o no se reduce a calcular los tiempos de ejecución de la rutina
antes y después de incluir en el procesador monociclo la instrucción aw.
Supongamos que procesador monociclo estudiado en clase y que no incluye la instrucción aw, en este caso el tiempo de
ejecución vendrá dado por la expresión:
tantes = NºInstruccionesantes×CPI×TCiclo_antes
Dados los valores de los parámetros del enunciado, el cuerpo del bucle se ejecuta 8 veces, con lo que NºInstruccionesantes = 1
(add) + 1 (xor) + 8×( 1 (slt) + 1 (beq) + 1 (sll) + 1 (add) + 1 (lw) + 1 (add) + 1 (addi) + 1 (j) ) + 1 (slt) + 1 (beq) + 1 (jr) = 2 +
8×8 + 3 = 69. Con lo que como tciclo_antes sabemos que es 8 ns. y el CPI es 1 (procesador monociclo) nos queda que tantes =
69×1×8 = 552 ns.
Cuando incluimos la nueva instrucción en el procesador monociclo se modifican tanto el NºInstrucciones como el tiempo de
ciclo del procesador. Ahora NºInstruccionesdespués = 1 (add) + 1 (xor) + 8×( 1 (slt) + 1 (beq) + 1 (sll) + 1 (add) + 1 (aw) + 1
(addi) + 1 (j) ) + 1 (slt) + 1 (beq) + 1 (jr) = 2 + 8×7 + 3 = 61. Tciclo_despues = 10 ns. y el CPI sigue siendo 1, con lo que tdespués =
61×1×10 = 610 ns.
Vemos como después de incluir la nueva instrucción el tiempo de ejecución del programa ha aumentado, por lo que podemos
concluir que no es conveniente el aumentar el procesador monociclo con esta nueva instrucción.
e)
Para la ejecución de la instrucción en el caso multiciclo son exactamente los mismos que los mostrados en el apartado
anterior. De esta manera la instrucción requerirá un total de 6 ciclos de reloj para ejecutarse. En el caso multiciclo el tiempo
de ciclo viene determinado por la etapa más lenta, que a partir de los retardos que nos dan, es la de ALU o la de acceso a
memoria (2 ns.). En este caso ambas versiones del procesador (con o sin incluir la instrucción aw) van a tener el mismo ciclo
de reloj, es decir 2ns. Lo que cambia ahora es el número de ciclos empleados para ejecutar el programa, dado que para el
caso multiciclo la expresión del tiempo de ejecución la podemos escribir como tejecución = NºCiclos×TCiclo= NºCiclos×2.
De esta forma, el procesador más rápido será aquel que requiera menos ciclos de reloj para ejecutar el programa:
NºCiclosantes = 4 (add) + 4 (xor) + 8×( 4 (slt) + 3 (beq) + 4 (sll) + 4 (add) + 5 (lw) + 4 (add) + 4 (addi) + 3 (j) ) + 4 (slt) + 3
(beq) + 4 (jr) = 8 + 8×31 + 11 = 267.
NºCiclosdespués = 4 (add) + 4 (xor) + 8×( 4 (slt) + 3 (beq) + 4 (sll) + 4 (add) + 6 (aw) + 4 (addi) + 3 (j) ) + 4 (slt) + 3 (beq) + 4
(jr) = 8 + 8×28 + 11 = 243.
Por lo tanto para el caso multiciclo el incluir la instrucción aw es beneficioso y el tiempo de ejecución del código es menor
que cuando no la tenemos. Conviene, pues, en este caso ampliar el procesador con la nueva instrucción.
2.- Utilizando la metodología vista en clase para la inclusión de nuevas instrucciones en el esquema de implementación
multiciclo, realizar la Fases de Análisis y Diseño de una nueva instrucción, incrcte, que permite incrementar en un valor
constante el contenido del registro $x, y guardar el resultado de la suma de la dirección de memoria apuntada por $y y una
constante en el registro $y:
incrcte $x, $y, cte
# $x = $x + cte
# $y = Memoria[$y] + cte
Solución:
En primer lugar debemos de proceder a identificar el uso que se va a realizar de los tres elementos básicos del camino de
datos: Banco de Registros, ALU y Memoria.
•
•
•
Banco de Registros: Leer $x, Leer $y, Escribir $x, Escribir $y
ALU: $x+cte, Memoria[$y]+cte
Memoria: Leer Memoria[$y]
A continuación debemos de establecer el orden en que se deben de realizar estas operaciones a partir de las dependencias
existentes para llegar a una planificación del trabajo a realizar en los diferentes ciclos de ejecución:
Banco Reg:
Leer $x
Leer $y
Escribir $x
$x+cte
Leer Memoria[$y]
ALU:
Memoria:
Escribir $y
Memoria[$y]+cte
(1) El incremento del registro $x sólo depende de que se haya hecho la lectura del registro correspondiente previamente.
(2) La escritura del registro $x se realiza, una vez que se haya realizado la operación aritmética $x+cte.
(3) La lectura de la dirección de memoria apuntada por $y depende de la lectura previa de dicho registro.
(4) La operación aritmética Memoria[$y]+cte depende de la lectura previa de memoria.
(5) La escritura del registro $y se realiza, una vez que se haya realiza la operación aritmética Memoria[$y]+cte.
Ciclos:
Banco Reg:
2
Leer $x
Leer $y
3
4
5
Escribir $x
$x+cte
Leer Memoria[$y]
ALU:
Memoria:
Escribir $y
Memoria[$y]+cte
Formato a dar a la instrucción:
Formato (I):
Ciclos:
Banco de
Reg.:
ALU:
Memoria:
incrcte
2
A=Leer $x
B=Leer $y
$x
$y
cte
3
ALUOut=$x+cte
MDR=Leer Memoria[$y]
4
5
$x=ALUOut
$y=ALUOut
ALUOut=Memoria[$y]+cte
En gris aparecen aquellas operaciones que no podemos realizar con la ruta de datos actual. Será necesario modificar la ruta
de datos para hacerlo posible.
Leer Memoria[$y]: Anadir una nueva entrada al multiplexor controlado por señal de control IorD procedente de la salida del
registro B.
ALUOut=Memoria[$y]+cte: Añadir una nueva entrada al multiplexor controlado por la señal de control ALUSrcA
procedente de la salida del registro MDR.
$x=ALUOut: Añadir una nueva entrada al multiplexor controlado por señal de control RegDst procedente de la salida del
registro de instrucción 25-21.
Descargar