Está en la página 1de 26

Memoria Práctica 1.

Carlos Jiménez López y Adrián Rubio Garrido


1.
a)
Instrucción Descripción

data A: .word 10,11,12,13,14,15,16,17,18,19

B: .word 20,21,22,23,24,25,26,27,28,29

C: .word 30,31,32,33,34,35,36,37,38,39 .text

daddi R1,R0,0 Suma de inmediato. R0 + 0 y lo almacena en R1

daddi R4,R0,0 Suma de inmediato. R0+ 0 y lo almacena en R4

daddi R20,R0,72 Suma de inmediato. R0 + 72 y lo almacena en


R20

daddi R19,R0,8 Suma de inmediato. R0 + 8 y lo almacena en R19

daddi R18,R0,10 Suma de inmediato. R0 + 10 y lo almacena en


R18

daddi R17,R0,1 Suma de inmediato. R0 + 1 y lo almacena en R17

daddi R16,R0,2 Suma de inmediato. R0 + 2 y lo almacena en R16

daddi R5,R0,40 Suma de inmediato. R0 + 40 y lo almacena en R5

bucle: INICIO DEL BUCLE

daddi R1,R1,8 Suma de inmediato. R1 + 8 y lo almacena en R1

daddi R4,R4,1 Suma de inmediato. R4 + 1 y lo almacena en R4

slt R3,R1,R5 Comprueba si el contenido de R3 es menor que


R5 y lo almacena en R1

beq R3,R0,else Comprueba si R3 es igual R0, ese caso, salta a


else

ld R10,A(R1) Carga en R10 el valor de R1 con un


desplazamiento A

daddi R11,R10,10 Suma de inmediato. R10 + 10 y lo almacena en


R11

sd R11,A(R1) Almacena en la posición R1 con desplazamiento


A el valor del registro R11
daddi R2,R1,8 Suma de inmediato. R1 + 8 y lo almacena en R2

ld R12,B(R2) Carga de la posición R1 con desplazamiento A el


valor del registro R11

dadd R12,R12,R16 Suma del contenido de registros. R12 + R16 y lo


almacena en R12

dadd R12,R11,R12 Suma del contenido de registros. R12 + R11 y lo


almacena en R12
sd R12,B(R1) Almacena en la posición R1 con desplazamiento
A el valor del registro R11

dadd R13,R12,R4 Suma del contenido de registros. R12 + R4 y lo


almacena en R13

sd R13,C(R1) Almacena en la posición R13 con


desplazamiento A el valor del registro R11

bne R1,R20,bucle Comprueba si R1 es igual R20, ese caso, salta a


bucle

j fin Salta a fin

else
dsub R6,R1,R19 Resta del contenido de registros. R1 – R19 y lo
almacena en R6

ld R10,A(R6) Carga de la posición R1 con desplazamiento A el


valor del registro R11

dsub R11,R10,R18 Resta del contenido de registros. R10 – R18 y lo


almacena en R11

sd R11,A(R1) Almacena en la posición R1 con desplazamiento


A el valor del registro R11

bne R1,R20,bucle Comprueba si R1 es igual R20, ese caso, salta a


bucle

fin:

ld R10,A(R0) Carga de la posición R0 con desplazamiento A el


valor del registro R10

daddi R11,R10,5 Suma de inmediato. R10 + 5 y lo almacena en


R11

sd R11,A(R0) Almacena en la posición R17 con


desplazamiento A el valor del registro R11
sd R17,B(R0) Almacena en la posición R17 con
desplazamiento B el valor del registro R11
sd R17,C(R0) Almacena en la posición R17 con
desplazamiento C el valor del registro R11

halt ACABA

b)
Necesita un total de 253 ciclos si ejecutamos el código sin ninguna optimización

Instrucción Descripción

data A: .word 10,11,12,13,14,15,16,17,18,19

B: .word 20,21,22,23,24,25,26,27,28,29

C: .word 30,31,32,33,34,35,36,37,38,39 .text

daddi R1,R0,0 Se ejecuta correctamente.

daddi R4,R0,0 Se ejecuta correctamente.

daddi R20,R0,72 Se ejecuta correctamente.

daddi R19,R0,8 Se ejecuta correctamente.

daddi R18,R0,10 Se ejecuta correctamente.

daddi R17,R0,1 Se ejecuta correctamente.

daddi R16,R0,2 Se ejecuta correctamente.

daddi R5,R0,40 Se ejecuta correctamente.

bucle:

daddi R1,R1,8 Se ejecuta correctamente.

daddi R4,R4,1 Se ejecuta correctamente.

slt R3,R1,R5 Existe un riesgo de datos puesto que se necesita


el registro R1 de la instrucción 9, se resuelve
mediante 1 parada.
beq R3,R0,else Existe un riesgo de datos puesto que se necesita
R3 de la instrucción anterior, que se resuelve
con 3 paradas.
ld R10,A(R1) Existe un riesgo estructural que se soluciona con
2 paradas.
daddi R11,R10,10 Existe un riesgo de datos puesto que se necesita
R10 de la instrucción anterior, que se resuelve
con 2 paradas.
sd R11,A(R1) Existe un riesgo de datos puesto que se necesita
R11 de la instrucción anterior, que se resuelve
con 4 paradas.
daddi R2,R1,8 Existe un riesgo estructural que se soluciona con
2 paradas.
ld R12,B(R2) Existe un riesgo de datos puesto que se necesita
R2 de la instrucción anterior, que se resuelve
con 2 paradas.
dadd R12,R12,R16 Existe un riesgo de datos puesto que se necesita
R12 de la instrucción anterior, que se resuelve
con 4 paradas.
dadd R12,R11,R12 Existe un riesgo de datos puesto que se necesita
R12 de la instrucción anterior, que se resuelve
con 4 paradas.
sd R12,B(R1) Existe un riesgo de datos puesto que se necesita
R11 de la instrucción anterior, que se resuelve
con 4 paradas.
dadd R13,R12,R4 Existe un riesgo estructural que se soluciona con
2 paradas.
sd R13,C(R1) Existe un riesgo de datos puesto que se necesita
R13 de la instrucción anterior, que se resuelve
con 2 paradas.
bne R1,R20,bucle Existe un riesgo estructural que se soluciona con
2 paradas.
j fin

else:

dsub R6,R1,R19 Se ejecuta correctamente.

ld R10,A(R6) Existe un riesgo de datos puesto que se necesita


R6 de la instrucción anterior, que se resuelve
con 2 paradas.
dsub R11,R10,R18 Existe un riesgo de datos puesto que se necesita
R10 de la instrucción anterior, que se resuelve
con 4 paradas.
sd R11,A(R1) Existe un riesgo de datos puesto que se necesita
R11 de la instrucción anterior, que se resuelve
con 4 paradas.
bne R1,R20,bucle Existe un riesgo estructural que se soluciona con
2 paradas.
fin:
ld R10,A(R0) Se ejecuta correctamente.

daddi R11,R10,5 Existe un riesgo de datos puesto que se necesita


R10 de la instrucción anterior, que se resuelve
con 2 paradas.
sd R11,A(R0) Existe un riesgo de datos puesto que se necesita
R11 de la instrucción anterior, que se resuelve
con 4 paradas.
sd R17,B(R0) Existe un riesgo estructural que se soluciona con
2 paradas.
sd R17,C(R0) Se ejecuta correctamente.

halt Se ejecuta correctamente.

c)
Necesita un total de 159 ciclos si ejecutamos el código con adelantamiento activados

El speedup, como resultado del cociente de CPIs, 2126/1336 = 1,59

Con el adelantamiento obtenemos cambios como:

Todas las instrucciones anteriores al fragmento encabezado por la etiqueta bucle se ejecutan
correctamente y sin variación respecto a la ejecución sin adelantamientos

Instrucción Descripción
daddi R1,R1,8 No sufre cambios
daddi R4,R4,1 No sufre cambios
slt R3,R1,R5 Se elimina una parada en la etapa ID ya
que se produce un adelantamiento de
R1 desde la primera instrucción hasta la
tercera.
beq R3,R0,else Se elimina una parada por riesgo
estructural, ya que, con el
adelantamiento producido en la
instrucción anterior, ya no hay riesgo de
coincidencia en la etapa ID. Además, se
produce un adelantamiento de R3 de la
instrucción anterior, de modo que en la
etapa ID evitamos dos paradas.
ld R10,A(R1) Nos encontramos con una instrucción
interrumpida, sin embargo, notamos la
diferencia respecto a la ejecución sin
adelantamiento porque en la
instrucción anterior hay una parada
menos en ID, de modo que la siguiente
instrucción se inicia un ciclo antes
dsub R6,R1,R19 No hay cambios
ld R10,A(R6) Se adelanta R6 desde la instrucción
anterior de EX a EX evitando dos
paradas por riesgo de datos
dsub R11,R10,R18 Al haber evitado las dos paradas
nombradas en la instrucción séptima,
prescindimos ahora de dos paradas por
riesgo estructurales (esto se produce
desde esta instrucción hasta la número
10), además se produce una
adelantamiento de R10 desde memoria
a EX(raw)
sd R11,A(R1) Se produce una parada estructural a fin
de no coincidir dos etapas EX y se
produce un adelantamiento desde EX
de la resta anterior hasta EX de esta.
bne R1,R20,bucle En lugar de desaparecer las dos
repetidas estas últimas instrucciones,
solo se elimina una por riesgo
estructural
ld R10,A(R0) Instrucción abortada
Vuelta a comenzar el bucle, no saldrá
de este hasta la ejecución de la
instrucción dadddi R11, R10, 5
dadddi R11, R10, 5 Se produce una parada en EX para
conseguir un adelantamiento de la
instrucción anterior de R10 desde
memoria hasta el propio EX
sd R11,A(R0) Se prescinde de dos paradas
estructurales debido a la variación
ocasionada por el adelantamiento
anterior, aunque se mantiene una
parada de un ciclo por el mismo riesgo.
También se produce adelantamiento de
R11 de Ex a Ex
sd R17,B(R0) Parada por riesgo estructural
sd R17,C(R0) No sufre cambios
halt No sufre cambios
d)
El speedup, como resultado del cociente de CPIs 1336/1188 = 1,31

Número de ciclos totales 133.

.data

A: .word 10,11,12,13,14,15,16,17,18,19

B: .word 20,21,22,23,24,25,26,27,28,29

C: .word 30,31,32,33,34,35,36,37,38,39

.text

daddi R1,R0,0

daddi R4,R0,0

daddi R20,R0,72

daddi R19,R0,8

daddi R18,R0,10

daddi R17,R0,1

daddi R16,R0,2

daddi R5,R0,40

bucle: daddi R1,R1,8

daddi R4,R4,1

slt R3,R1,R5

ld R10,A(R1)

beq R3,R0,else

daddi R11,R10,10

daddi R2,R1,8

ld R12,B(R2)

dadd R12,R12,R16

sd R11,A(R1)

dadd R12,R11,R12

dadd R13,R12,R4

sd R12,B(R1)

sd R13,C(R1)
bne R1,R20,bucle

j fin

else: ld R10,A(R6)

dsub R6,R1,R19

dsub R11,R10,R18

bne R1,R20,bucle

sd R11,A(R1)

fin: ld R10,A(R0)

sd R17,B(R0)

daddi R11,R10,5

sd R17,C(R0)

sd R11,A(R0)

halt

e)
Los casos posibles de rellenado de la ranura de salto que podemos aplicar son tres.

El primero consiste en rellenar la ranura con una instrucción anterior al salto, la segunda, con
una dirección del destino del salto y la tercera con una instrucción de la dirección de salto no
tomado.

En este ejercicio, tenemos dos instrucciones de salto condicional:

La primera instrucción:

bne R1,R20,bucle

La segunda instrucción:

bne R1,R20,bucle

En el caso de este apartado, a diferencia de los dos siguientes, el código no tiene un sentido o
una función. Por ello, la reordenación del código es mucho más flexible. Para la primera
instrucción rellenaremos la ranura con la instrucción sd R13,C(R1), es decir, una instrucción
anterior al salto.

Y para la segunda la rellenaremos con la instrucción dsub R11,R10,R18, es decir, una


instrucción de dirección de salto no tomado.

El speedup, como resultado del cociente de CPIs, 1181/1064 = 1,10


De tal modo que el código queda así:

.data

A: .word 10,11,12,13,14,15,16,17,18,19

B: .word 20,21,22,23,24,25,26,27,28,29

C: .word 30,31,32,33,34,35,36,37,38,39

.text

daddi R1,R0,0

daddi R4,R0,0

daddi R20,R0,72

daddi R19,R0,8

daddi R18,R0,10

daddi R17,R0,1

daddi R16,R0,2

daddi R5,R0,40

bucle: daddi R1,R1,8

daddi R4,R4,1

slt R3,R1,R5

ld R10,A(R1)

beq R3,R0,else

daddi R11,R10,10

daddi R2,R1,8

ld R12,B(R2)

dadd R12,R12,R16

sd R11,A(R1)

dadd R12,R11,R12

dadd R13,R12,R4

sd R12,B(R1)

bne R1,R20,bucle

sd R13,C(R1)
j fin

else: ld R10,A(R6)

dsub R6,R1,R19

bne R1,R20,bucle

dsub R11,R10,R18

sd R11,A(R1)

fin: ld R10,A(R0)

sd R17,B(R0)

daddi R11,R10,5

sd R17,C(R0)

sd R11,A(R0)

halt
2
a)
Instrucción Descripción
jal mul Se ejecuta correctamente
nop Es necesaria ya que de no existir, la instrucción
que se inicia automáticamente después del jal
por la predicción de salto no tomado, ejecutaría
el halt y terminaría el programa.
daddi r1,r0,64 Se ejecuta correctamente
daddi r5,r0,63 Se ejecuta correctamente
daddu r2,r0,r0 Se ejecuta correctamente
daddu r10,r0,r0 Se ejecuta correctamente
ld r3,x(r0) Se ejecuta correctamente
ld r4,y(r0) Se ejecuta correctamente
andi r9,r3,1 Se produce una parada para que este escrito el
resultado de la instrucción 7 y así poder hacer el
EX
dsub r9,r0,r9 Parada por riesgo estructural en F, y para de dos
ciclos en D para que este escrito r9
dsrl r3,r3,1 Parada por riesgo estructural en f
--- Empieza el bucle
and r6,r4,r9 Se ejecuta correctamente. (En la primera
iteración: Se produce un riesgo Raw, con el
registro R9, por tanto, una parada.)
daddu r2,r2,r6 Necesita dos paradas para que escriba R6 que
calcula en la instrucción anterior. (primera
iteración: además necesita una parada en la
etapa F por riesgo estructural)
sltu r7,r2,r6 Necesita dos paradas en la etapa F por riesgo
estructural, y dos paradas en la etapa D por
riesgo Raw con el registro R2
dsllv r7,r7,r5 Necesita dos paradas en la etapa F por riesgo
estructural, y dos paradas en la etapa D por
riesgo Raw con el registro R7
andi r10,r2,1 Necesita dos paradas en F por riesgo estructural
dsllv r10,r10,r5 Necesita dos paradas en D por riesgo RAW en el
registro R10
dsrl r2,r2,1 Dos paradas en F por riesgo estructural
or r2,r2,r7 Necesita dos paradas por riesgo Raw con el
registro R2
andi r9,r3,1 Necesita dos paradas en F por riesgo estructural.
dsub r9,r0,r9 Necesita dos paradas por riesgo RAW con el
registro R9
dsrl r3,r3,1 Necesita dos paradas por riesgo estructural en F
or r3,r3,r10 Necesita dos paradas en D por riesgo RAW con el
registro R3
daddi r1,r1,-1 Necesita dos paradas por riesgo estructural en F
bnez r1,again Necesita dos paradas en D por riesgo raw en con
el registro R1
sd r2,w(r0) Inicia la instrucción predicha por salto no
tomado y la aborta
-----------------------BUCLE---------------------- ------------------------------BUCLE--------------------------
sd r2,w(r0) (Fin de bucle). Necesita dos paradas por riesgo
estructural en F
sd r3,w+8(r0) Se ejecuta correctamente
jr r31 Se ejecuta correctamente
Aborta
nop Se ejecuta correctamente
halt Se ejecuta correctamente

b)
Si ejecutamos el código inicial con adelantamientos, desaparecen todas las paradas analizadas
en el apartado a, excepto la parada de la instrucción bnez r1,again. Por tanto, como tiene
dependencia con la instrucción inmediatamente anterior y el desplazamiento de esta no
influye en el código, la ejecutamos una instrucción antes. El total de ciclos obtenidos es 980

De este modo nuestro código queda tal que así.

.data

x: .word 0xFFFFFFFFFFFFFFFF

y: .word 0xFFFFFFFFFFFFFFFF

w: .word 0,0

.text

start: jal mul ; llamada a una subrutina

nop ; ¿por que es necesario un NOP? Respondido en la tabla

halt

mul: daddi r1,r0,64 ; r1 = 64 bits

daddi r5,r0,63 ; todo 1's para shift

daddu r2,r0,r0 ; r2=0

daddu r10,r0,r0 ; r10=0

ld r3,x(r0) ; r3=x

ld r4,y(r0) ; r4=y
andi r9,r3,1 ; LSB de x

dsub r9,r0,r9 ; negado

dsrl r3,r3,1 ; shift a la derecha

again: and r6,r4,r9

daddu r2,r2,r6

sltu r7,r2,r6 ; overflow?

dsllv r7,r7,r5 ; overflowed bit

andi r10,r2,1 ; copia el LSB de r2 ..

dsllv r10,r10,r5 ; .. lo pega como MSB de r3

dsrl r2,r2,1 ; shift

or r2,r2,r7 ; or overflowed bit

andi r9,r3,1 ; LSB

dsub r9,r0,r9 ; negado

dsrl r3,r3,1 ; shift and ...

daddi r1,r1,-1 ; queda un bit menos que computar

or r3,r3,r10 ; ... copia MSB

bnez r1,again

sd r2,w(r0) ; 64-bits mas significativos

sd r3,w+8(r0) ; 64-bits menos significativos

jr r31 ; regresa de la función


c)
Los casos posibles de rellenado de las ranuras de salto que podemos aplicar son tres.

El primero consiste en rellenar la ranura con una instrucción anterior al salto, la segunda, con
una dirección del destino del salto y la tercera con una instrucción de la dirección de salto no
tomado.

En este ejercicio, donde solo tenemos una instrucción de salto condicional:

bnez r1, again

De este modo, como dicha instrucción pertenece al fragmento de código encabezado por la
etiqueta a la que salta, no podemos poner la instrucción destino del salto en la ranura porque
dejaría de ser funcional. Tampoco podemos rellenar la ranura con la instrucción anterior ya
que alteraría el código. Por tanto la instrucción que rellena la ranura es la de salto no tomado
sd r2,w(r0)

Por otro lado, encontramos una instrucción jal, cuya ranura rellenaremos con la instrucción del
destino del salto. Las otras dos opciones quedan descartadas ya que, no existe una instrucción
anterior (es la primera) y la instrucción de salto no tomado es nop, la cual, como se ha
explicado antes existe con tal de que no se comience a ejecutar el halt. Es decir, no tiene
sentido dejar la instrucción nop si podemos ejecutar en su lugar una que sea necesaria para el
desarrollo del código.

El total de ciclos es 979

El código queda tal que así:

; Multiplicacion de dos numeros sin signo de 64-bits en MIPS964

; El resultaddo es un numero de 128-bits w = x * y

.data

x: .word 0xFFFFFFFFFFFFFFFF

y: .word 0xFFFFFFFFFFFFFFFF

w: .word 0,0

.text

start: jal mul ; llamada a una subrutina

daddi r1,r0,64 ; r1 = 64 bits

halt
mul: daddi r5,r0,63 ; todo 1's para shift

daddu r2,r0,r0 ; r2=0

daddu r10,r0,r0 ; r10=0

ld r3,x(r0) ; r3=x

ld r4,y(r0) ; r4=y

andi r9,r3,1 ; LSB de x

dsub r9,r0,r9 ; negado

dsrl r3,r3,1 ; shift a la derecha

again: and r6,r4,r9

daddu r2,r2,r6

sltu r7,r2,r6 ; overflow?

dsllv r7,r7,r5 ; overflowed bit

andi r10,r2,1 ; copia el LSB de r2 ..

dsllv r10,r10,r5 ; .. lo pega como MSB de r3

dsrl r2,r2,1 ; shift

or r2,r2,r7 ; or overflowed bit

andi r9,r3,1 ; LSB

dsub r9,r0,r9 ; negado

dsrl r3,r3,1 ; shift and ...

daddi r1,r1,-1 ; queda un bit menos que computar

or r3,r3,r10 ; ... copia MSB

bnez r1,again

sd r2,w(r0) ; 64-bits mas significativos

sd r3,w+8(r0) ; 64-bits menos significativos

jr r31 ; regresa de la funcion


3
a)
Instrucción Descripción
lwu r8,DATA(r0) Se ejecuta correctamente
lwu r9,CONTROL(r0) Se ejecuta correctamente
daddi r11,r0,4 Se ejecuta correctamente
daddi r1,r0,titulo Se ejecuta correctamente
sd r1,(r8) Se necesitan dos paradas en D por
riesgo de datos con R1
sd r11,(r9) Se necesitan dos paradas por riesgos
estructurales en F
daddi r1,r0,pregunta; Se ejecuta correctamente
sd r1,0(r8) Se necesitan dos paradas en D por
riesgo de datos con R1
sd r11,0(r9) Se necesitan dos paradas por riesgos
estructurales en F
daddi r1,$zero,8 Se ejecuta correctamente
sd r1,0(r9) Se necesitan dos paradas en D por
riesgo de datos con R1
ld r1,0(r8) Se necesitan dos paradas por riesgos
estructurales en F
sd r1,max(r0) Se necesitan dos paradas en D por
riesgo de datos con R1
daddi r12,r0,1 Se necesitan dos paradas por riesgos
estructurales en F
---------------------------BUCLE---------------------------
andi r3,r1,1 Se ejecuta correctamente
beqz r3,par Se necesitan dos paradas en D por
riesgo Raw con R3
--------------------------Caso Par--------------------------
daddu r2,r1,r1 Instrucción tomada por predicción de salto no
tomado, se aborta
dsrl r1,r1,1 Se ejecuta correctamente
-------------Máximo (Par, no toma salto)------------
sd r1,(r8) Se necesitan dos paradas en D por
riesgo RAW con R1
sd r12,(r9) Se necesitan dos paradas por riesgo estructural
en F
ld r4,max(r0) Se ejecuta correctamente
slt r3,r4,r1 Se necesitan dos paradas en D por
riesgo RAW con R4
beqz r3,fin Se necesitan dos paradas por riesgo
estructural en F y dos paradas en D por
riesgo RAW con R3
sd r1,max(r0) Se necesitan dos paradas por riesgo
estructural en F
---------------------Fin (desde par) ----------------
slti r3,r1,2 Se ejecuta correctamente
beqz r3,bucle Se necesitan dos paradas en D por riesgo RAW
con R3
ld r2,max(r0) Predicción de salto no tomado, aborta
instrucción.
En este punto, se repite hasta la tercera
iteración, en la cual todo se mantiene igual a
excepción del trozo de Máximo, donde esta vez
sí toma el salto. Por tanto,
------------Máximo (desde Par, toma salto)---------
sd r1,(r8) Se necesitan dos paradas en D por riesgo RAW
con R1
sd r12,(r9) Se necesitan dos paradas por riesgo estructural
en F
ld r4,max(r0) Se ejecuta correctamente
slt r3,r4,r1 Se necesitan dos paradas en D por riesgo RAW
con R4
beqz r3,fin Se necesitan dos paradas por riesgo estructural
en F y dos paradas en D por riesgo RAW con R3
sd r1,max(r0) Instrucción abortada
---------------------Fin (desde par) ---------------------
slti r3,r1,2 Se ejecuta correctamente
beqz r3,bucle Se necesitan dos paradas en D por riesgo RAW
con R3
-------------------------Si toma salto---------------------
ld r2,max(r0) Predicción de salto no tomado, aborta
instrucción.
Vuelve a bucle
-----------------------Si no toma salto-------------------
ld r2,max(r0) Se necesitan dos paradas por riesgo estructural
daddi r1,r0,str Se ejecuta correctamente
sd r1,(r8) Se necesitan dos paradas en D por riesgo Raw
con R1
sd r11,(r9) Se necesitan dos paradas en F por riesgo
estructural
sd r2,(r8) Se ejecuta correctamente
sd r12,(r9) Se ejecuta correctamente
Halt Se ejecuta correctamente

b)
Si activamos lo adelantamientos, todas las paradas producidas por los diferentes riesgos
en las instrucciones comprendidas entre a 1 y la 15 desaparecen

A continuación, si ejecutamos el código mediante Run To, muchas paradas necesarias sin
adelantamientos son resueltas, sin embargo, hay algunas que permanecen o aparecen.

La primera que se no muestra es la en la instrucción:

beqz r3,bucle, la cual tiene una parada en D por riesgo Raw.


Esta parada no la podemos evitar por reordenación de código ya que, la instrucción se
encuentra al inicio del fragmento encabezado por la etiqueta fin. La dependencia de datos
que tiene es con la instrucción anterior, la primera de este fragmento, y ambas juntas nos
indican si el programa debe ejecutarse hasta el final o volver al bucle, de modo que no
podemos alterarlo.

La siguiente parada que encontramos es en la instrucción

beqz r3,par

de manera similar a la anterior, se encuentra al inicio del fragmento bucle, por lo que no
podemos reordenarlo, para así no alterar la toma de decisión de par o impar

La siguiente parada que encontramos es en la instrucción

slt r3, r4, r1

Necesita de una parada en EX por resigo Raw con R4 que se le adelanta desde Mem de la
instrucción anterior. Con esta instrucción si que podemos reordenar el código, de modo
que sea la primera instrucción en ser ejecutada al iniciar el fragmento de código
encabezado por la etiqueta máximo. Esto es posible ya que las dos instrucciones que se
situaban anteriormente de dependen de la que estamos estudiando en ningún parámetro.
(sd r1,(r8) y sd r12,(r9))

El total de ciclos es de 445

El código quedaría tal que así:

; Conjetura de Collatz

; Impares: multiplica por 3 y suma 1

; Pares: divide entre 2

; Repetir hasta llegar a 1

; ¿Cual es el valor maximo alcanzado?

.data

max: .word 0 ; maximo

titulo: .asciiz "Conjetura de Collatz\n"

pregunta: .asciiz "Numero= "

str: .asciiz "Maximo= "

; Memory Mapped I/O area


;

; Address of CONTROL and DATA registers

; Set CONTROL = 1, Set DATA to Unsigned Integer to be output

; Set CONTROL = 2, Set DATA to Signed Integer to be output

; Set CONTROL = 3, Set DATA to Floating Point to be output

; Set CONTROL = 4, Set DATA to address of string to be output

; Set CONTROL = 5, Set DATA+5 to x coordinate, DATA+4 to y coordinate, and DATA to RGB
colour to be output

; Set CONTROL = 6, Clears the terminal screen

; Set CONTROL = 7, Clears the graphics screen

; Set CONTROL = 8, read the DATA (either an integer or a floating-point) from the keyboard

; Set CONTROL = 9, read one byte from DATA, no character echo.

CONTROL: .word32 0x10000

DATA: .word32 0x10008

.text

lwu r8,DATA(r0) ; r8 = DATA

lwu r9,CONTROL(r0) ; r9 = CONTROL

daddi r11,r0,4 ; Activa string

daddi r1,r0,titulo ; direccion en memoria de titulo

sd r1,(r8) ; datos a imprimir (titulo)

sd r11,(r9) ; datos en String

daddi r1,r0,pregunta; direccion en memoria de pregunta

sd r1,0(r8) ; datos a imprimir (pregunta)

sd r11,0(r9) ; datos en String


daddi r1,$zero,8 ; r1 = 8

sd r1,0(r9) ; CONTROL = 8

ld r1,0(r8) ; r1 = Numero introducido

sd r1,max(r0) ; max = r1

daddi r12,r0,1 ; r12 = 1

bucle: andi r3,r1,1 ; par o impar?

beqz r3,par

impar: daddu r2,r1,r1 ;x2

dadd r1,r2,r1 ; x 3

daddi r1,r1,1 ; mas 1

j maximo

par: dsrl r1,r1,1 ; div 2

maximo: ld r4,max(r0) ; r4 = max

sd r1,(r8) ; DATA = r1

sd r12,(r9) ; CONTROL = 1

slt r3,r4,r1 ; max < r1

beqz r3,fin

sd r1,max(r0) ; max = r1

fin: slti r3,r1,2 ; test for finished

beqz r3,bucle

ld r2,max(r0) ; r2 = max

daddi r1,r0,str ; direccion de str

sd r1,(r8) ; DATA = "Maximum="

sd r11,(r9) ; CONTROL = 4
sd r2,(r8) ; DATA = max

sd r12,(r9) ; CONTROL = 1

halt

c)
La primera instrucción de salto que encontramos es la del bloque encabezado por la
etiqueta bucle

beqz r3,par

En este caso, la ranura solo la podemos rellenar con la instrucción de salto no tomado
impar: daddu r2,r1,r1. Esto se debe a que la instrucción anterior es la que le pasa el
registro r3 a la condición del salto, por tanto, debe ejecutarse antes. Y la de rellenar la
ranura con la instrucción de la dirección del salto el código se altera.

La siguiente instrucción de salto que encontramos es:

beqz r3,fin

Para eta instrucción descartamos rellenar la ranura con una instrucción anterior ya que es
la que determina el registro que evlúa la condición de salto. Ahora, entre las otras dos
posibles, rellenar con la dirección de salto o con la de salto no tomado, la más eficiente es
el rellenado con la de la dirección de salto. slti r3,r1,2;

Por último, tenemos la instrucción:

beqz r3,bucle

Para rellenar esta ranura descartamos la opción la dirección de salto ya que es un


fragmento anterior del código, que de moverla alteraría el código. Ahora, de entre las dos
restantes la más eficaz es la de rellenar la ranura con la instrucción de salto no tomado.

El total de ciclos obtenidos con este código es de 315.

El código queda así:

; Conjetura de Collatz

; Impares: multiplica por 3 y suma 1

; Pares: divide entre 2

; Repetir hasta llegar a 1

; ¿Cual es el valor maximo alcanzado?

.data

max: .word 0 ; maximo


titulo: .asciiz "Conjetura de Collatz\n"

pregunta: .asciiz "Numero= "

str: .asciiz "Maximo= "

; Memory Mapped I/O area

; Address of CONTROL and DATA registers

; Set CONTROL = 1, Set DATA to Unsigned Integer to be output

; Set CONTROL = 2, Set DATA to Signed Integer to be output

; Set CONTROL = 3, Set DATA to Floating Point to be output

; Set CONTROL = 4, Set DATA to address of string to be output

; Set CONTROL = 5, Set DATA+5 to x coordinate, DATA+4 to y coordinate, and DATA to RGB
colour to be output

; Set CONTROL = 6, Clears the terminal screen

; Set CONTROL = 7, Clears the graphics screen

; Set CONTROL = 8, read the DATA (either an integer or a floating-point) from the keyboard

; Set CONTROL = 9, read one byte from DATA, no character echo.

CONTROL: .word32 0x10000

DATA: .word32 0x10008

.text

lwu r8,DATA(r0) ; r8 = DATA

lwu r9,CONTROL(r0) ; r9 = CONTROL

daddi r11,r0,4 ; Activa string

daddi r1,r0,titulo ; direccion en memoria de titulo


sd r1,(r8) ; datos a imprimir (titulo)

sd r11,(r9) ; datos en String

daddi r1,r0,pregunta; direccion en memoria de pregunta

sd r1,0(r8) ; datos a imprimir (pregunta)

sd r11,0(r9) ; datos en String

daddi r1,$zero,8 ; r1 = 8

sd r1,0(r9) ; CONTROL = 8

ld r1,0(r8) ; r1 = Numero introducido

sd r1,max(r0) ; max = r1

daddi r12,r0,1 ; r12 = 1

bucle: andi r3,r1,1 ; par o impar?

beqz r3,par

impar: daddu r2,r1,r1 ; x 2

dadd r1,r2,r1 ;x3

daddi r1,r1,1 ; mas 1

j maximo

par: dsrl r1,r1,1 ; div 2

maximo: ld r4,max(r0) ; r4 = max

sd r1,(r8) ; DATA = r1

sd r12,(r9) ; CONTROL = 1

slt r3,r4,r1 ; max < r1

beqz r3,fin

slti r3,r1,2 ; test for finished

sd r1,max(r0) ; max = r1
fin: beqz r3,bucle

ld r2,max(r0) ; r2 = max

daddi r1,r0,str ; direccion de str

sd r1,(r8) ; DATA = "Maximum="

sd r11,(r9) ; CONTROL = 4

sd r2,(r8) ; DATA = max

sd r12,(r9) ; CONTROL = 1

halt

También podría gustarte