Blog Practicas AC Grupo 2 B4
domingo, 13 de enero de 2013
Componentes y organización
Componentes:
-Jose Alberto Jiménez Serrano
- Cristian Macías García
-Victor Mendoza Gardón
-Rafael Gargallo Garretas
-Samuel Rodríguez Mera
-Alvaro Moreno Ladrón de Guevara (Coordinador)
Organización y exposición:
-Rafael Gargallo Garretas ( Práctica 1-2) --> Expondrá práctica 1
- Cristian Macías García ( Práctica 5-7) --> Expondrá práctica 5
-Jose Alberto Jiménez Serrano ( Práctica 6-7) --> Expondrá práctica 7
-Victor Mendoza Gardón ( Práctica 3.4,8) --> Expondrá práctica 4
-Samuel Rodríguez Mera (Práctica 3)
Metodologia:
Se ha intentado fomentar el trabajo en grupo (parejas de 2) a desarollar en todas las practicas
excepto las prácticas 1 y 2 que son mas de recopilar datos, de las cuales se ha encargado Rafael.
Como se puede observar la carga de trabajo para los distintos miembros del grupo no ha sido
equitativa debido a algunos problemas con uno de los componentes.
Desde aquí decir que el máximo responsable respecto a lo anterior soy yo, ya que para eso soy el
coordinador y ademas quiero agradecer a los integrantes responsables de mi grupo que hayan hecho
trabajo que no les correspondia con la mejor de sus sonrisas.
Alvaro.
sábado, 12 de enero de 2013
Práctica 8
Grado en Ingeniería Informática
Arquitectura de Computadores – Prácticas Curso 2012-13
P8 - PRÁCTICAS CON WinDLXV
PRÁCTICA 2
El siguiente programa (pract2v1.s) se encarga de multiplicar todos los números de la lista
almacenada por el número pi, dejando los resultados almacenados en las mismas posiciones.
Considerar inicialmente las siguientes opciones de configuración:
-
Unidad de suma: latencia 2 ciclos
-
Unidad de multiplicación: latencia 5 ciclos
-
Unidad de división: latencia 19 ciclos
-
Unidades funcionales sin segmentar
-
Saltos: predicción de no tomar
-
Adelantamiento de resultados: desactivado
Para empezar debemos establecer la configuración que nos indica el enunciado:
Configuración → Arquitectura (Ctrl+A)
*Para obtener los valores de latencia deseados en el enunciado debemos poner los que aparecen en
la imagen.
En el mismo menú Configuración, desactivamos adelanto de resultados y la opción de saltos la
dejamos tal cual, es decir, predicción de no tomar.
1.-
a) Simular el programa y determinar la ganancia de velocidad que se obtiene si se permiten caminos
de bypass (opción adelantamiento de resultados activada).
Primero ejecutamos las instrucciones con la opción adelantamiento de resultados desactivada,
obtenemos lo siguiente:
A(pract2v1.s)
Ahora activaremos la opción adelantamiento de resultados y obtenemos los siguientes resultados:
B
Comparando estos resultados tenemos que:
Velocidad = Prestaciones = 1/ciclos
VelocidadA = PrestacionesA = 1/392 = 0,002551102
VelocidadB = PrestacionesB = 1/294 = 0,003401361
PrestacionesB / PrestacionesA = 0,003401361 / 0,00255110 = 1,333
Luego con el adelantamiento de resultados activado, habrá una ganancia de velocidad del 33%.
b) Partiendo de la configuración inicial, considere que se efectúa una mejora en la unidad de
multiplicación, reduciendo su retardo a 3 ciclos. Esta mejora supone un incremento del coste del
15%. Determine si, para el este programa,
compensa realizar dicha mejora desde el punto de vista de la relación coste/prestaciones.
Para este apartado la configuración será la siguiente:
Configuración → Arquitectura (Ctrl+A)
Como ya sabemos del enunciado anterior la configuración inicial produce los siguientes resultados:
A(pract2v1.s)
Con la latencia de multiplicación reducida, obtenemos lo siguiente:
B
Comparando estos resultados tenemos que:
Velocidad = Prestaciones = 1/ciclos
VelocidadA = PrestacionesA = 1/392 = 0,002551102
VelocidadB = PrestacionesB = 1/344 = 0,002906977
PrestacionesB / PrestacionesA = 0,002906977 / 0,002551102 = 1,13
Viendo los resultados, esta mejora nos aumentará el coste un 15% y a cambio nos dará un
rendimiento 13% mayor, por lo que no es una mejora efectiva en relación coste/prestaciones.
c) Considere que la mejora consiste en reducir el retardo de la unidad de
multiplicación a 2 ciclos, con un incremento del coste del 18%. ¿Compensa la mejora?
Para este apartado la configuración será la siguiente:
Configuración → Arquitectura (Ctrl+A)
Como ya sabemos del enunciado anterior la configuración inicial produce los siguientes resultados:
A(pract2v1.s)
Con la latencia de multiplicación reducida, obtenemos lo siguiente:
B
Comparando estos resultados tenemos que:
Velocidad = Prestaciones = 1/ciclos
VelocidadA = PrestacionesA = 1/392 = 0,002551102
VelocidadB = PrestacionesB = 1/320 = 0,003125
PrestacionesB / PrestacionesA = 0,003125 / 0,002551102 = 1,224
Viendo los resultados obtenidos, esta mejora nos aumentará el coste un 18% y a cambio nos dará un
rendimiento 22% mayor, por lo que es una mejora efectiva en relación coste/prestaciones.
d) ¿Tendría interés mejorar la latencia de la unidad de suma?
No seria efectiva, ya que si observamos en la ventana estadística un poco mas abajo, observamos las
instrucciones de tipo suma que se llevan a cabo:
A la vista de esto, no tendrá ningún interés mejorar la latencia de suma.
2.-
Seleccione la opción “salto retardado” y ejecute el programa. ¿Qué ocurre? ¿Cuál es la causa?
¿Cuál sería la solución?
En el salto retardado se reordena el código de forma que se sitúan instrucciones que no dependan
del salto después del mismo para que se vayan ejecutando esas instrucciones (que siempre se van a
ejecutar) y cuando se termine de calcular el salto se toma o no. Pero en este programa hay un
problema. Lo que pasa es que antes de que se decida el salto, como se siguen ejecutando
instrucciones, Se ejecuta la Trap de salida antes de que se tome el salto. Por eso solo hace una
iteración del bucle y finaliza, con lo cual no se ejecuta bien el programa. La solución sería poner
más instrucciones independientes a ejecutarse después del salto, para que no se ejecute el trap antes
de coger el salto.
3.-
La siguiente figura (pract2v2.s) muestra una versión modificada del código inicial, que se ha
transformado aplicando una técnica que recibe el nombre de desenrollado de bucle. Esta técnica
consiste en realizar los cálculos de varias iteraciones en una única iteración para reducir así el
número de instrucciones de salto que se tienen que ejecutar, con lo que además se evitan riesgos de
control. Determinar la ganancia de velocidad que se obtiene con respecto a la versión inicial del
programa.
Como ya sabemos del enunciado anterior la configuración inicial produce los siguientes resultados:
A(pract2v1.s)
Con la versión mejorada del programa obtenemos los siguientes resultados:
B(pract2v2.s)
Comparando estos resultados tenemos que:
Velocidad = Prestaciones = 1/ciclos
VelocidadA = PrestacionesA = 1/392 = 0,002551102
VelocidadB = PrestacionesB = 1/302 = 0,003311258
PrestacionesB / PrestacionesA = 0,003311258 / 0,002551102 = 1,29
Luego el nuevo programa ha producido una ganancia de velocidad del 29% respecto al anterior.
4.-
Para el programa del apartado anterior, pract2v2.s, determinar la ganancia de velocidad que se
obtiene con respecto a un procesador DLX sin segmentar de referencia, que denominaremos
DLXssr.
En el procesador DLXssr cada instrucción va pasando por distintas fases que se suceden según sean
utilizadas por la correspondiente instrucción, de forma que las instrucciones tendrán distinto tiempo
de ejecución según del tipo que sean.
Consideraremos que en DLXssr las fases IF, ID, intEX, MEM y WB tienen un ciclo de reloj cada
una. Las fases faddEX, fmultEX y fdivEX tendrán el mismo número de ciclos que en el caso del
procesador segmentado.
Para estimar el tiempo de ejecución del programa en DLXssr hay que tener en cuenta el tiempo que
tardaría cada una de sus instrucciones. El tiempo de una instrucción se puede determinar a partir del
número de etapas por las que pasa. Así, por ejemplo, una instrucción de carga (ld) pasaría por todas
las etapas (duración 5 ciclos de reloj) mientras que una instrucción de almacenamiento (sd) no
pasaría por WB (duración 4 ciclos de reloj) ya que no tiene que almacenar nada en los registros del
procesador. Las instrucciones aritmético-
lógicas no pasarían por la etapa MEM. Hay que tener en
cuenta que la duración de la etapa EX depende del tipo de instrucción: si la operación es con
enteros, se utilizará intEX y la duración será de un ciclo; si es en coma flotante, se utilizará faddEX,
fmulEX o fdivEX y la duración será la asignada a la correspondiente unidad.
Para las instrucciones de salto condicional considere una duración de 3 ciclos (en la etapa de
ejecución se comprueba la condición y se carga en el PC la nueva dirección, si fuese el caso). Para
el trap considere 2 ciclos (hasta la etapa de decodificación).
En un procesador sin segmentar cada instrucción se ejecuta independientemente, por lo tanto el
tiempo que tarde en ejecutarse cada instrucción dependerá del numero de ciclos que tenga. Por lo
tanto para hacer la comparación entre este procesador y el segmentado, debemos ver el numero de
instrucciones que tenemos de cada tipo en el programa y los ciclos que cada una necesita.
Pues veamos entonces:
Tenemos 24 elementos en el vector. A cada uno de ellos lo sacamos del vector y lo multiplicamos
por PI y lo guardamos en el mismo sitio.
Por cada elemento → ld(cargar en registro) multd(multiplicar) y sd(volver a guardarlo en el mismo
sitio).
Luego 3 instrucciones por elemento 3*24 =72 instrucciones.
Además, se hacen más instrucciones. En cada iteración del bucle se hace una resta y la
comparación del salto. En esta versión del programa en cada iteración se multiplican 4 elementos
del vector,
Luego 24/4 =6 iteraciones, es decir 6(iteraciones)*2(instrucciones) = 12 instrucciones.
Se ejecutan al principio otras dos instrucciones (una carga y una suma). Y al final otra (trap).
Tenemos en total : 72+12+2+trap = 87 instrucciones.
Ahora veamos los ciclos que tardan cada instrucción y multipliquemos por el número de
instrucciones que hubiera de ese tipo. (LW dura 5 ciclos, pero sw y add duran solo 4 ciclos,
mientras que el salto dura 3 ciclos y la trap 2)
LD (load double) → 24 instrucciones * 5 ciclos = 120 ciclos;
MultD → Tienen 4 ciclos pero hay que contar la latencia de mult, que es 5 ciclos, luego son
3(IF,ID, WB) + 5 de ejecutar la operación = 8 ciclos /instrucción * 24 instrucciones = 192 ciclos.
SD (store double) → 24 instrucciones * 4 ciclos = 96 ciclos.
Subi (substract inmediate) → se hacen 6 instrucciones que duran 4 ciclos (son restas de enteros),
luego 6*4=24 ciclos.
Beqz (El salto) 6 instrucciones * 3 ciclos = 18 ciclos.
De las dos instrucciones del principio, la carga es de 5 ciclos, y la suma de 4, luego 9 ciclos.
trap vale 2 ciclos.
Sumando en total salen 120+192+96+24+18+9+2= 461 ciclos.
Pues bien ya tenemos los datos, ahora comparemos entre ambos procesadores:
A(pract2v2.s)
B: 461 Ciclos
87 Instrucciones
Comparando estos resultados tenemos que:
Velocidad = Prestaciones = 1/ciclos
VelocidadA = PrestacionesA = 1/302 = 0,003311258
VelocidadB = PrestacionesB = 1/461 = 0,002169197
PrestacionesA / PrestacionesB = 0,003311258 / 0,002169197 = 1,52
Luego a tenor de los resultados obtenidos, el procesador segmentado es un 52% mas rápido.
5.-
Modificar el programa del apartado 3 (pract2v3.s) de forma que incluya 8 iteraciones en el
bucle. Determinar la ganancia de velocidad que se obtiene con respecto a las versiones anteriores.
La versión modificada quedaría de la siguiente forma:
.data 0
a: .double 3.14159265358979
x: .double 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
.double 17,18,19,20,21,22,23
xtop: .double 24
.text 256
start: ld f2,a
addi r1,r0,xtop
loop: ld f0,0(r1)
multd f4,f0,f2
sd 0(r1),f4
ld f6,-8(r1)
multd f8,f6,f2
sd -8(r1),f8
ld f10,-16(r1)
multd f12,f10,f2
sd -16(r1),f12
ld f14,-24(r1)
multd f16,f14,f2
sd -24(r1),f16
ld f18,0(r1)
multd f20,f18,f2
sd -32(r1),f20
ld f22,-8(r1)
multd f24,f22,f2
sd -40(r1),f24
ld f26,-16(r1)
multd f28,f26,f2
sd -48(r1),f28
ld f30,-24(r1)
multd f6,f30,f2
sd -56(r1),f6
subi r1,r1,64
bnez r1,loop
trap 6
Ahora comparemos los resultados de ambas versiones del programa:
A(pract2v2.s)
B(pract2v3.s)
Comparando estos resultados tenemos que:
Velocidad = Prestaciones = 1/ciclos
VelocidadA = PrestacionesA = 1/302 = 0,003311258
VelocidadB = PrestacionesB = 1/287 = 0,003484321
PrestacionesB / PrestacionesA = 0,003484321 / 0,003311258 = 1,11
Con esta nueva versión del programa hemos obtenido una ganancia de velocidad del 11%.
6.-
Partiendo de la versión del apartado 3, reorganizar las instrucciones (pract2v4.s) para reducir el
efecto de las dependencias entre ellas. Simular la versión realizada y determinar la ganancia de
velocidad obtenida.
Pues bien ahora reorganizaremos las instrucciones dentro del bucle, de forma que primero haremos
las 4 instrucciones de tipo ld(cargar en registro), luego las 4 multd(multiplicar) y por ultimo las 4
sd(volver a guardarlo en el mismo sitio).
La nueva versión del programa quedaría de la siguiente forma:
.data 0
a: .double 3.14159265358979
x: .double 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
.double 17,18,19,20,21,22,23
xtop: .double 24
.text 256
start: ld f2,a
addi r1,r0,xtop
loop: ld f0,0(r1)
ld f6,-8(r1)
ld f10,-16(r1)
ld f14,-24(r1)
multd f4,f0,f2
multd f8,f6,f2
multd f12,f10,f2
multd f16,f14,f2
sd 0(r1),f4
sd -8(r1),f8
sd -16(r1),f12
sd -24(r1),f16
subi r1,r1,32
bnez r1,loop
trap 6
Veamos los resultados obtenidos, primero vemos el que ya conocemos pract2v2.s (A) y luego
pract2v4.s(B).
A(pract2v2.s)
B(pract2v4.s)
Comparando estos resultados tenemos que:
Velocidad = Prestaciones = 1/ciclos
VelocidadA = PrestacionesA = 1/302 = 0,003311258
VelocidadB = PrestacionesB = 1/200 = 0,005
PrestacionesB / PrestacionesA = 0,005 / 0,003311258 = 1,51
Con esta nueva versión del programa (pract2v4.s), hemos obtenido una ganancia de velocidad del
51%.
Práctica 7
Grado en Ingeniería Informática
Arquitectura de Computadores – Prácticas Curso 2012-13
Arquitectura de Computadores – Prácticas Curso 2012-13
Practica 7: WinDLXV
Para la
realización de esta práctica emplearemos el simulador WinDLXV con objeto de
identificar las posibles detenciones del pipeline y observar las etapas por las
que pasa una instrucción.
REALIZACIÓN
DE LA PRÁCTICA.
En esta práctica analizaremos 4
conjuntos de instrucciones y contestaremos a una serie de cuestiones. Para
estos 4 ejemplos las condiciones de partida son:
- Unidad de
suma: latencia 2 ciclos
- Unidad de
multiplicación: latencia 5 ciclos
- Unidad de
división: latencia 19 ciclos
- Unidades
funcionales sin segmentar
- Adelantamiento de resultados:
desactivado
Ejemplo 1: dependencias de datos tipo RAW
Cargamos
el programa del ejemplo 1.
Cuestiones:
·
¿Cuál es en este cauce la latencia de
emisión de las instrucciones aritmético-lógicas?
Con latencia de emisión nos referimos a los ciclos que
existen entre una instrucción y la siguiente. En este caso hay 2 ciclos entre
instrucciones aritmético-lógicas.
·
¿La escritura y la lectura de los
operandos en el banco de registros se realizan en el mismo o en distinto ciclo?
Se realizan en un mismo ciclo, una operación en el flanco de
subida y otra en el de bajada.
a) Número total
de ciclos de ejecución : 29
Ciclos.
CPI: 1933 Ciclos/Inst.
b) Número (de
ciclos) y distribución de las detenciones (stalls): Se producen 10 detenciones de tipo RAW.
c) Aplicando el
adelantamiento de resultado se obtienen los siguientes resultados:
Número total de ciclos de ejecución: 19 Ciclos.
CPI: 1267 Ciclos/Inst.
Número (de ciclos) y distribución
de las detenciones y ganancia del rendimiento al emplear adelantamiento de
resultados (data forwarding) :
Ninguna
detención. Al emplear adelantamiento de resultados se produce una mejora en el
número de ciclos de ejecución y de reloj.
Ejemplo
2: dependencias de datos tipo RAW
Cargamos el programa del ejemplo 2 modificando los registros y las
posiciones de memoria pedidos.
ADD
r1,r2,r3 r1 = 1002 + 6
= 0x1008
LW r4, 0(r1) r4 = 0x20
SUB r5,r4,r3 r5 = r4 – r3 = 0x1a
SW 14(r2),r5
almacena 1a en la posición 0x1010
de memoria.
LW r1, 2(r2) r1 = 0x1f
SUB r4,r1,r5 r4 = 0x5
AND r6, r1, r5 r6 = 0x1a
OR r8,r1,r5 r8 = 0x1f
Cuestiones
·
¿Cuál es en este cauce la latencia de emisión
de las instrucciones aritmético-lógicas?
La latencia de las
instrucciones Aritmético-lógicas es de 1 ciclo.
¿Y para las instrucciones de
carga?
La latencia de
las instrucciones de carga es de 3
ciclos.
a) Número total
de ciclos de ejecución: 25 ciclos.
CPI: 1923 Ciclos/Inst.
b) Número (de
ciclos) y distribución de las detenciones:
Se producen 8 detenciones de tipo
RAW.
c) Aplicando el
adelantamiento de resultado se obtienen los siguientes resultados:
Número total de ciclos de ejecución: 19 ciclos.
CPI: 1462 Ciclos/Inst.
Número (de ciclos) y distribución de las
detenciones: 2
detenciones tipo RAW.
Ganancia del rendimiento al emplear
adelantamiento de resultados: 7 ciclos
menos, 6 RAW menos.
d) Al emplear
adelantamiento de resultados, ¿cuáles serían las latencias de emisión para las
instrucciones aritmético-lógicas y para las instrucciones de carga?
Con adelantamiento de resultado, la latencia de las
instrucciones aritmético-lógicas es de 1 ciclo y la de las instrucciones de
carga es de 2 ciclos.
Ejemplo 3:
dependencias de tipo estructural
Cargamos
el programa del ejemplo 3.
Cuestiones
a) Número total
de ciclos de ejecución: 18 ciclos.
CPI: 3
Ciclos/Inst.
b) Número (de
ciclos) y distribución de las detenciones :
No existen detenciones.
c)
Ganancia del rendimiento al
segmentar las unidades funcionales de punto flotante:
15 Ciclos de
ejecución.
CPI: 2.5
ciclos/instrucción.
Mejora el
rendimiento al disminuir los ciclos de
ejecución y los ciclos de reloj.
Ejemplo 4:
reordenación de datos
Cargamos
el programa del ejemplo 4 modificando la latencia de las instrucciones señaladas.
Cuestiones
a) Número total
de ciclos de ejecución: 86 ciclos.
CPI del programa inicial: 7167 Ciclos/Inst.
b) Número de
ciclos perdidos por dependencias tipo RAW en el programa inicial:
35 detenciones tipo RAW.
c) Ganancia del
rendimiento al reordenar las instrucciones:
Se produce una mejora del rendimiento porque el número de
ciclos de ejecución disminuye de 86 a 73, el número de ciclos por instrucción
de 7.167 a 6.083 y el número de
detenciones de 35 a 17.
Práctica 6
Grado en Ingeniería Informática
Arquitectura de Computadores – Prácticas Curso 2012-13
Práctica 6:Simulación de
ejecución en la realización monociclo del procesador MIPS.
Para la
realización de esta práctica utilizaremos el simulador SIMULA3MS con el
objetivo de identificar el camino de datos del procesador monociclo MIPS. Este
simulador implementa un subconjunto de instrucciones basadas en el repertorio
de instrucciones del procesador MIPS.
REALIZACIÓN
DE LA PRÁCTICA.
1.
Primeramente cargamos en el
simulador el programa Programa1.
Ensamblamos
y comprobamos que no se produce ningún error. Una vez comprobamos que no
contiene errores, damos a ejecutar para iniciar el proceso de simulación de
ejecución del programa.
2.
Una vez hecho esto, avanzamos hacia
la última instrucción lw haciendo uso del botón “Ciclo siguiente” y respondemos
a las siguientes cuestiones:
2.1. Localice
e indique los elementos necesarios del camino de datos que realiza esta instrucción
de tipo I:
Los elementos necesarios para la
realización de esta instrucción son:
-
El Contador de
Programa (PC).
-
La Memoria de
Instrucciones.
-
El Banco de
Registros.
-
La Unidad
Aritmético – Lógica.
-
La Memoria de
Datos.
-
Un mecanismo
para la extensión de signo, ya que se trata de una instrucción de tipo I.
-
La Unidad de
Control (UC), para el control de los distintos multiplexores.
2.2.
Describa con palabras y
con lenguaje RTL todas las operaciones que tienen lugar hasta completar esta
instrucción lw $s0,0($t1).
Primero se incrementa el contador de
programa. De la Memoria de Instrucciones se lee la instrucción (32 bits) de la
cual los 6 bits más significativos se pasan a la UC, que decodifica la
instrucción y determina la salida de cada Multiplexor.
Al ser una instrucción de tipo I, los
bits de 25 – 21 se emplean para el Registro Fuente, los del 20 – 16 para el
Registro destino y los del 15 – 0 de offset necesarios, junto al Registro
Fuente, para obtener el dato a almacenar. Este dato se almacenará en el
Registro Destino.
Del Banco de Registros se le pasa a la
ALU la dirección del R. Fuente y la
dirección de offset, que debe pasar por la extensión de signo para que la ALU
pueda operar con él. Éstas direcciones se suman y da como resultado la dirección
del dato almacenado en la Memoria de Datos. El dato obtenido se escribe en el
registro indicado por los bits 20 – 16 de la instrucción.
2.3.
Indique el valor, en hexadecimal, que toman los siguientes registros y buses:
PC:
0040000c
Instrucción
[31-0]: 8d300000
Instrucción
[25-21]: 09
Instrucción
[20-26]: 10
Instrucción
[15-0]: 0000
Bus
de 32 bits tras la extensión de signo: 00000000
Dato
leído 1: 00000009
Resultado
de la ALU (ó dirección de memoria de datos): 00000009
Dato
leído en memoria de datos: 0000000a
Dato
a escribir en el banco de registros: 0000000a
3. Ahora,
avanzamos hacia la úlima instrucción lw. Cambia en algo el proceso ya descrito
de realización de la instrucción lw? ¿Qué valores toman ahora los siguientes
registros y buses?
Observando
el camino de datos, podemos ver que
es idéntico al de la primera instrucción lw, por tanto, el proceso de
realización de la instrucción es el mismo.
Instrucción
[15-0]: 000c
Bus de 32
bits tras la extensión de signo: 0000000c
4.
En este ejercicio avanzamos hasta
la instrucción add y respondemos a las siguientes cuestiones:
4.1. Indique las
operaciones que tienen lugar para la ejecución de dicha instrucción.
Primero se incrementa el contador de
programa. De la Memoria de Instrucciones se lee la instrucción (32 bits) de la
cual los 6 bits más significativos se pasan a la UC junto con los 6 bits menos
significativos, utilizados para el código de la función que determina la
operación a realizar en la ALU. La UC decodifica la instrucción y determina la
salida de cada Multiplexor.
Al ser una instrucción de tipo II, los
bits de 25 – 21 se emplean para el primer Registro Fuente, los del 20 – 16 para
el segundo Registro Fuente, los del 15 –
11 para el Registro Destino, los del 10 – 6 no se utilizan, y por último, los
bits 5- 0 para el código de la función.
Del Banco de Registros se le pasa a la
ALU la dirección del primer R. Fuente y
la dirección del segundo R. Fuente. De ahí se leen los dos daos que se
transfieren a la ALU, dónde se opera con ellos. El resultado se escribe en el
R. Destino indicado por los bits 15 – 11.
4.2.
¿Se trata del mismo camino de datos utilizado para la instrucción Lw?.
No, no es el mismo camino de datos. En el caso de la
instrucción lw, sólo tenemos un registro Fuente, y en este caso son dos los
registros a acceder en el banco de registros. No necesitamos los bits de offset
necesarios en una instrucción lw. Cuando en una instrucción add operamos en la
ALU, el resultado no ni se escribe ni se lee en memoria de datos, por lo que no
tenemos que acceder a ella. En la imagen se muestra el camino de datos de la
instrucción add.
5. Vuelva
a la instrucción lw y observe cómo algunas líneas de control aparecen
destacadas sobre las demás usando otro tono del color naranja. ¿Qué líneas de
control actúan para cada una de las instrucciones analizadas?
Lw: MemRead, MemSrc, ALUsrc, RegWrite.
Add: RegDest,
ALU operation, RegWrite.
Práctica 5
Grado en Ingeniería Informática
Arquitectura de Computadores – Prácticas Curso 2012-13
Ensamblador
del procesador MIPS
Simula3MS
El desarrollo de esta práctica se basa en la programación en ensamblador
del procesador MIPS. Para programar en este lenguaje usaremos el programa
SIMULA3M. Disponible en: http://simula3ms.des.udc.es/
El manual usado para
entender el simulador está disponible en el siguiente enlace.
https://docs.google.com/open?id=0B_QYUG73pxy8ekFxWTFOTnlIZzQ
Los ejercicios propuestos para esta práctica son
los siguientes:
Ejercicios
1-4
Los ejercicios propuestos del 1 al 4 se resumen como:
-
Ejercicio
1: Entender el entorno y hacer uso del manual
-
Ejercicio
2: Escribir el programa de ejemplo siguiente.
-
Ejercicio
3: Ensamblar y comprobar posibles errores en el código.
-
Ejercicio
4: Repasar sintaxis si existen errores. En caso contrario ejecutar para
iniciar el proceso de simulación de ejecución.
Observamos que al ensamblar el código no existen
errores, por lo que pasamos a la ejecución.
Ejercicio 5
En este ejercicio pide ejecutar el programa anterior
paso a paso haciendo uso del botón de “Ciclo Siguiente”.
Observamos que para cada tipo de instrucción se
muestra el camino de datos de un color distinto.
Los
registros pedidos en el ejercicio y su contenido son:
$t0: 10010000 $s0: 00000064
$t1: 10010004 $s1: fffffff6
$t2: 10010008 $s2: 0000005a
Los datos
de la memoria de datos son los siguientes:
Dirección
0x10010000: 0x00000064
Dirección
0x10010004: 0xfffffff6
Dirección 0x10010008: 0x0000005a
Ejercicio 6
Este ejercicio pide escribir el código siguiente
usando el editor, ensamblarlo y ejecutarlo. Y posteriormente explicarlo.
Inicialmente en este programa se carga un vector de 4
elementos, donde cada elemento es un número decimales ya definido. En el cuerpo
del programa se carga la dirección de memoria del vector en la variable $t1.
Luego, las 4 siguientes instrucciones cargan de la memoria de datos el valor de
cada posición del vector a partir de $t1 y el desplazamiento en las variables
$s0, $s1, $s2 y $s3.
El contenido del segmento de datos de memoria al
inicio de la ejecución es el siguiente:
0x10010000: 0x000000d2
0x10010004: 0x000000f0
0x10010008: 0x0000014a
0x1001000c: 0x00001608
Observamos
los siguientes valores:
-
Contenido del registro t1 antes de la ejecución: t1:
0x00000000
-
Valor del registro PC antes de la ejecución: PC: 00400000
-
Contenido del registro t1 después de la ejecución: t1:
10010000
-
Contenido de los registros siguientes al término de la
ejecución:
s0: 000000d2
s1: 000000f0
s2: 0000014a
-
Valor del registro PC al término de la ejecución: PC:
00400018
Ejercicio 7
Este ejercicio pide que se escriba el siguiente código
usando el editor de Simula3MS, ensamble, ejecute y compruebe el resultado.
Código:
.data
.text
.globl main
main:
li
$a0,0x0000000F
li
$v0,0x00000001 # La llamada
asociada con imprimir por pantalla
# un entero es la 1
syscall # Efectúa la llamada y
muestra por pantalla
# el decimal 15
li
$v0,0x0000000A # La llamada que
indica al procesador que
# se terminado la ejecución es EXIT,
# de
código 10 decimal
syscall # Efectúa la llamada
Debemos saber que para pedir un servicio hay que
cargar el código de la llamada deseada en el registro de MIPS denominado $v0 y
los argumentos que se van a mostrar o leer en los registros $a0 ó $a1. Una vez
establecidos estos valores se procederá a efectuar la llamada con syscall.
Tras
ensamblar y ejecutar el código observamos que el resultado mostrado es 15.
Ejercicio
8
Este ejercicio se pide la realización de un programa
que solicita por teclado tres valores enteros y los almacena en memoria en un
vector llamado “vector” para el que previamente se habrán reservado cuatro
palabras de memoria, tres para los enteros introducidos y un cuarto para
guardar el resultado final. Luego se completa el programa efectuando la suma de
los elementos del vector construido y se muestra por pantalla.
El programa es el siguiente:
.data
vector: .word 0,0,0,0
.text
.globl main
main:
#Insercción de números
la $t1,vector # Apunta a la
dirección del 1º elemento de
li $v0,5
syscall
sw $v0,0($t1)
li $v0,5
syscall
sw $v0,4($t1)
li $v0,5
syscall
sw $v0,8($t1)
#Cargar elementos del vector para sumarlos
lw $s0,0($t1) # Carga el 1º
elemento del vector en s0
lw $s1,4($t1) # Carga el 2º
elemento del vector en s1
lw $s2,8($t1) # Carga el 3º
elemento del vector en s2
add $t0,$s0,$s1 # Suma
elementos 1 y 2
add $t0,$t0,$s2 # Suma el
resultado del anterior y elemento 3
sw $t0,12($t1) # Almacena el
resultado de la suma en la última posición del vector
lw $a0, 12($t1) # Carga el
resultado
li $v0, 1 # Muestra por
pantalla
syscall
Suscribirse a:
Entradas (Atom)