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.
***********************************************************
.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 (1)
addi r1,r0,xtop (2)
loop: ld f0,0(r1) (3)
multd f4,f0,f2 (4)
sd 0(r1),f4 (5)
subi r1,r1,8 (6)
bnez r1,loop (7)
trap 6 (8)
***********************************************************
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
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).
318 ciclos frente a 416 sin
adelantamiento. Se obtiene una ganancia de velocidad de 98 ciclos.
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 este programa, compensa
realizar dicha mejora desde el punto de vista de la relación coste/prestaciones.
Sin adelantamiento: 368 ciclos frente
a 416 ciclos. La mejora es de 48 ciclos. Se mejoraría un 11,54%. Relación
coste/prestaciones = 15% / 11,54% = 1,3%
Con
adelantamiento: 270 ciclos frente a 318 ciclos. La mejora es de 48 ciclos. Se
mejoraría un 15,09%. Relación coste/prestaciones = 15% / 15,09% = 0,99%
No
merece la pena realizar la mejora.
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?
Sin adelantamiento: 344 ciclos frente
a 416 ciclos. La mejora es de 72 ciclos. Se mejoraría un 17,31%. Relación
coste/prestaciones = 18% / 17,31% = 1,04%
Con
adelantamiento: 246 ciclos frente a 318 ciclos. La mejora es de 72 ciclos. Se
mejoraría un 22,64%. Relación coste/prestaciones = 18% / 22,64% = 0,795%
Merece
la pena realizar la mejora.
d) ¿Tendría interés mejorar la
latencia de la unidad de suma?
No, porque no se realizan suman, y
la única reducción posible es en 1 unidad y no merecería la pena.
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?
Se reduce a 25 ciclos. La causa es que
ya que puede acceder a la información antes, necesita menos ciclos para la
ejecución del programa.
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.
****************************************************************
.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 (1)
addi r1,r0,xtop (2)
loop: ld f0,0(r1) (3)
multd f4,f0,f2 (4)
sd 0(r1),f4 (5)
ld f6,-8(r1) (6)
multd f8,f6,f2 (7)
sd -8(r1),f8 (8)
ld f10,-16(r1) (9)
multd f12,f10,f2 (10)
sd -16(r1),f12 (11)
ld f14,-24(r1) (12)
multd f16,f14,f2 (13)
sd -24(r1),f16 (14)
subi r1,r1,32 (15)
bnez r1,loop (16)
trap 6 (17)
****************************************************************
Sin adelantamiento: 326 ciclos
frente a 416 ciclos de la versión inicial. Ganancia de velocidad en 90 ciclos.
Con adelantamiento: 246 ciclos
frente a 368 ciclos de la versión inicial. Ganancia de velocidad en 122 ciclos.
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).
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.
Para conseguir que el bucle tenga 8
iteraciones, eliminamos las líneas señaladas en negrita del código, y el 32 de
la línea siguiente, lo convertimos en un 24:
**********************************************************************
.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 (1)
addi r1,r0,xtop (2)
loop: ld f0,0(r1) (3)
multd f4,f0,f2 (4)
sd 0(r1),f4 (5)
ld f6,-8(r1) (6)
multd f8,f6,f2 (7)
sd -8(r1),f8 (8)
ld f10,-16(r1) (9)
multd f12,f10,f2 (10)
sd -16(r1),f12 (11)
ld f14,-24(r1) (12)
multd f16,f14,f2 (13)
sd -24(r1),f16 (14)
subi r1,r1,32 (15)
bnez r1,loop (16)
trap 6 (17)
**********************************************************************
El
nuevo código posee un 2% más de velocidad que el anterior.
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.
Para reducir el efecto de las
dependencias entre ellas, hemos cambiado el orden de las instrucciones de
lectura-escritura. Anteriormente, las de escritura estaban antes que las de
lectura, ya que el código contaba con muchas detenciones del tipo RAW. Al hacer
este cambio hemos obtenido una ganancia de velocidad del 17% con respecto a la
primera versión.
**********************************************************************
.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: addi r1,r0,xtop
ld
f2,a
loop: ld f0,0(r1)
multd
f4,f0,f2
ld
f6,-8(r1)
sd
0(r1),f4
multd
f8,f6,f2
ld f10,-16(r1)
sd
-8(r1),f8
multd
f12,f10,f2
ld
f14,-24(r1)
sd
-16(r1),f12
multd
f16,f14,f2
sd -24(r1),f16
subi
r1,r1,32
bnez
r1,loop
trap
6
**********************************************************************