Está en la página 1de 8

ARQUITECTURA DE COMPUTADORES I EXAMEN DE FEBRERO DE 2007

1. (2 puntos) Considere que el fragmento de cdigo siguiente:


(1) (2) (3) (4) (5) (6) lf lf addf sf lf addf f3, 0(r1) f2, 8(r1) f4, f2, f3 16(r1), f4 f5, 16(r2) f6, f5, f2 (7) (8) (9) (10) (11) (12) multf sf addi lf multf sf f6, f6, f4 8(r2), f6 r3, r2, #32 f7, 0(r3) f8, f7, f3 0(r3), f8

se ejecuta en un procesador superescalar que es capaz de captar (IF), decodificar/emitir (ID/ISS) y finalizar (WB) 4 instrucciones/ciclo. El procesador utiliza un ROB para realizar el renombramiento y la finalizacin ordenada y dispone de tres estaciones de reserva de 3 lneas cada una (una para las instrucciones de acceso a memoria, otra para las operaciones de coma flotante, y otra para las operaciones con enteros). Las estaciones de reserva pueden enviar una instruccin por ciclo a cada una de las unidades funcionales conectadas a ellas (la velocidad de envo depende, por tanto, del nmero de unidades que estn conectadas a cada estacin). El procesador permite los adelantamientos de stores por loads no especulativos, pero no permite los especulativos. (a) Indique el nmero de ciclos que tardara en ejecutarse el conjunto de instrucciones anterior suponiendo envo desordenado desde las estaciones de reserva a las unidades funcionales. (b) Y si el envo fuera ordenado desde las estaciones de reserva para operaciones con enteros y operaciones con datos en coma flotante, pero desordenado para la estacin de acceso a memoria? NOTA: Considere que, conectadas a la estacin de reserva para el acceso a memoria, tiene una unidad funcional de carga con un retardo de dos ciclos y una de almacenamiento con retardo de un ciclo; conectadas a la estacin de reserva para enteros tiene dos ALUs con retardo de un ciclo; y, conectadas a la estacin de reserva para coma flotante tiene una unidad de multiplicacin con cinco ciclos de retardo y dos unidades de suma con dos ciclos de retardo. No hay lmite en el nmero de lneas de la cola de instrucciones y del ROB). 2. (2 Puntos) Considere que el siguiente bucle: for i=1 to N do X[i] = a*Y[i]; X[i], Y[i] y a son nmeros en coma flotante

Se ejecuta en un procesador vectorial de 32 bits que dispone de una nica unidad para acceder a los datos de memoria. Los tiempos de latencia de inicio para los cauces son TLI(LV)=5 ciclos, TLI(MULTSV)=10 ciclos, y TLI(SV)=5 ciclos, y los registros vectoriales tienen 64 componentes (MVL=64). Se tiene que TBASE=15 ciclos, TBUCLE=10 ciclos, y la frecuencia del procesador es igual a 1 GHz (a) Cul es el valor de R? (b) Cul sera el cdigo escalar para una arquitectura LOAD/STORE que implemente la secuencia de instrucciones vectoriales anterior? (c) Suponga que el cdigo escalar se ejecuta en un procesador superescalar de 32 bits a 1 GHz que puede terminar un promedio de instrucciones por ciclo tal que el tiempo de ejecucin est limitado por el tiempo de acceso a los datos. El computador tiene una memoria cach interna para datos y otra para instrucciones de 64 KBytes cada una, lneas de 32 Bytes, mapeo directo, poltica de actualizacin de post-escritura (write-back), con asignacin de cach en escritura (write-allocate), y tiempo de acceso de un ciclo de reloj de CPU. La memoria principal de 512 MBytes tiene un tiempo de acceso de 50 ns y se conecta a travs de un bus de 64 bits a 100 MHz que utiliza ciclos burst 5-11-1 para transferir las lneas de cach. Si el array que se multiplica por el escalar tiene N=1024 elementos, se ejecuta antes en el procesador vectorial o en el superescalar? NOTA: Considere la situacin ms favorable respecto a la ubicacin de los arrays en memoria principal y su correspondencia en cach.

3. (2 Puntos) El siguiente fragmento de cdigo forma parte de una rutina que se ejecuta muy a menudo en cierto procesador VLIW:
mult add beqz lw add mult sub mult sw r1, r2, r3 r4, r5, r1 r4, cero r6, dato r7, r4, r6 r2, r1, r7 r8, r1, r4 r1, r8, r2 resul, r1

cero:

La arquitectura VLIW tiene dos slots, pero las instrucciones de comparacin slo pueden colocarse en el primero de ellos. Las latencias de las operaciones son de 1 ciclo para las sumas, restas y comparaciones, de dos ciclos para las multiplicaciones y de cinco ciclos para las cargas de memoria. Debido a esta alta latencia en el acceso a memoria, la arquitectura incorpora una instruccin de carga especulativa de memoria (lw.s rx, desp[ry], repar) que permite cargar un dato anticipadamente. Para dar soporte a esta instruccin, los registros del procesador cuentan con un bit de veneno adicional para marcar aquellos resultados en los que la especulacin haya provocado una excepcin. La aplicacin de cualquier operacin con un operando envenenado provocar que se envenene el resultado, y la excepcin slo se atender si se intenta almacenar un resultado envenenado. En dicho caso, tras atender la excepcin se ejecutar el cdigo de reparacin indicado con el puntero repar. Por otra parte, todas las instrucciones pueden predicarse y existen instrucciones de la forma (p) p1[,p2] cmp.cnd x,y donde cnd es la condicin que se comprueba entre x e y (lt, ge, eq, ne,). Si la condicin es verdadera p1=1 (y p2=0), y si es falsa, p1=0 (y p2=1). La instruccin slo se ejecuta si el predicado p=1. Optimice el cdigo anterior de manera que no aparezca ninguna instruccin de salto, se tengan en cuenta las latencias de las operaciones y los slots a los que se pueden emitir, y se adelante la instruccin de carga especulativamente todo lo que sea posible para tratar de ocultar su latencia. 4. (2 puntos) Considere un procesador con arquitectura DLX que implementa un cauce segmentado en cinco etapas (IF, ID, EX, MEM, WB). Para los nmeros en coma flotante se aaden adems un sumador con una latencia de 2 ciclos y un multiplicador con una latencia de 3 ciclos. Existen caminos de bypass desde la salida de las unidades de ejecucin y desde la etapa de memoria a las entradas de la ALU. Las instrucciones de salto se procesan en la etapa de decodificacin, por lo que la nueva direccin a la que se ha de acceder si se produce el salto estar disponible al final de dicha etapa. Se implementa salto retardado en el que no se anula nunca la siguiente instruccin que se haya podido introducir en el cauce tras un salto (el salto se resuelve en la etapa de decodificacin). Considerando el cdigo siguiente:
add subd bucle: ld multd addd addi subi bnez sd r1, r0, r0 f0, f0, f0 f2, X(r1) f6, f2, f4 f0, f0, f6 r1, r1, #8 r3, r3, #8 r3, bucle R, f0 ; ; ; ; ; ; ; ; ; Inicializamos el ndice i a 0 Inicializamos el acumulador a 0 Cargamos X(i) Multiplicamos X(i) por a (en f4) Acumulamos el resultado Incrementamos el contador del ndice Comprobamos si hemos acabado Saltamos si quedan elementos Guardamos el resultado

(a) Se ejecutara el programa correctamente tal y como est? Qu cambios hara para aprovechar el salto retardado? (b) Cul es la productividad del cauce en funcin del nmero de iteraciones N?

Solucin al Problema 1:
Suponiendo un envo desordenado para todas las estaciones de reserva, el cdigo tardara 28 ciclos en ejecutarse, tal y como se muestra en el siguiente diagrama:
1 (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) lf lf addf sf lf addf multf sf addi lf multf sf f3, 0(r1) f2, 8(r1) f4, f2, f3 16(r1), f4 f5, 16(r2) f6, f5, f2 f6, f6, f4 8(r2), f6 r3, r2, #32 f7, 0(r3) f8, f7, f3 0(r3), f8
IF IF IF IF

2
ID ID ID ID IF IF IF IF

3
EX X

4
EX X

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

ID ID ID X IF IF IF IF X X X X X

ROB WB EX EX ROB WB EX EX ROB WB EX WB EX

EX

ROB WB EX EX ROB WB EX EX

EX

EX

EX

ID ID X X X EX X X X ROB X X X X X X ID ID X ID

ROB WB EX WB WB EX EX ROB WB EX EX EX EX EX ROB WB EX WB

En el enunciado se especifica que las cargas podrn adelantar a los almacenamientos siempre que no sean especulativas, es decir cuando se sepa que va a acceder a direcciones de memoria diferentes. Las instrucciones (5) y (4), acceden a memoria con el mismo desplazamiento y dos registros ndice diferentes (r2 y r1), con lo que si r2 tuviera un valor diferente al de r1, la instruccin (5) podra adelantar a la (4). Como no sabemos los valores de estos registros, se ha supuesto el peor caso, que es la coincidencia de r1 y r2, lo que obliga a que la instruccin (5) tenga que esperar a la (4). Por otro lado, las instrucciones (10) y (8) acceden a posiciones de memoria diferentes, ya que la instruccin (8) almacena en la posicin 8+r2 y la instruccin (10) lee de la posicin 0+r3 = 32+r2. Como suponemos que las direcciones efectivas se calculan en el primer ciclo de la etapa de ejecucin de las instrucciones de acceso a memoria, aunque las direcciones finales sean diferentes, este hecho no se puede comprobar por la lgica de envo de la estacin de reserva, lo que obliga a enviar primero el almacenamiento y luego la carga. Estas dos dependencias estn marcadas en el diagrama mediante flechas de color amarillo. Las colisiones que se producen en el cauce estn marcadas con el smbolo X. Estas colisiones pueden ser bien en las estaciones de reserva o en las unidades de ejecucin. Como las estaciones de reserva tienen slo tres entradas cada una, cuando alguna se llena no permite que se puedan emitir ms instrucciones hacia ella hasta que enve alguna instruccin y deje algn hueco. Este fenmeno se puede apreciar en la instruccin (8), que no puede entrar hasta que se enva la instruccin (2) y se quedan en la estacin de reserva las instrucciones (4) y (5). Tambin se crea un cuello de botella en la estacin de reserva de acceso a memoria con la instruccin (10), que no puede emitirse hasta que se enva la instruccin (4), y que retrasa la emisin de la instruccin (11), ya que la emisin es ordenada. Por ltimo, la instruccin (12) se bloquear en la cola de instrucciones hasta que se enve a ejecutar la instruccin (5). En cuanto a las colisiones en las unidades de ejecucin, la instruccin (2) debe esperar a que la (1) libere la unidad de carga, y lo mismo ocurre entre las instrucciones (11) y (7) por el multiplicador y entre las instrucciones (10) y (5) al acceder a memoria. Por ltimo, los riesgos de datos adelantados por los caminos de bypass estn marcados mediante flechas negras en el diagrama. En el caso de que el envo fuese desordenado slo para la estacin de reserva de acceso a memoria, el resultado sera exactamente el mismo, ya que debido a los riesgos del programa, todas las instrucciones se han enviado ordenadamente.

Solucin al Problema 2:
Dado que el tamao de los registros vectoriales del procesador propuesto en el problema es MVL = 64 y que el vector que deseamos procesar tiene un tamao N que no est definido, tendremos que aplicar la tcnica de strip-mining para trocear el vector y procesarlo iterativamente. El compilador realizar un cambio al cdigo similar a este:
low = 1; VL = (n mod MVL); /* resto de la division */ for ( j = 0 ; j <= (n / MVL) ; j++) { for ( i = low ; i < low + VL ; i++) X(i):= a*Y(i); low += VL; VL = MVL; }

Al traducir este cdigo a ensamblador, el bucle que se encuentra sombreado se cambiar por instrucciones vectoriales y el resto de instrucciones permanecern tal y como estn. Dado que R se define como

R = lim Rk = lim
k

k operaciones vectoriales frecuencia k Tk

el primer paso consistir en estimar el tiempo Tk. Para ello, debemos determinar las instrucciones vectoriales que se ejecutarn dentro del bucle interno y la forma en que se solaparn y encadenarn. Dichas instrucciones sern la carga vectorial de Y, una multiplicacin, y un almacenamiento del resultado en X. El diagrama de tiempos de estas instrucciones es el siguiente:
5 10 LV VY, RY MULTSV VX, a, VY 5 5 64 64 5 SV RX, VX

Como slo tenemos una unidad de carga/almacenamiento, la instruccin SV debe esperar a que termine la instruccin LV, por tanto, tenemos que el tiempo por componente es TPC = 2 y que el tiempo de latencia inicial TLI = 5 + 5 = 10, ya que la multiplicacin ha quedado solapada con las instrucciones de carga y de almacenamiento. Con estos valores de TLI y TPC y con los valores de TBASE y TBUCLE que nos dan en el enunciado del problema, podemos calcular Tk como:

k k (TLI + TBUCLE ) + k TPC = 15 + (10 + 10) + 2k ciclos Tk = TBASE + 64 MLV


Una vez obtenido Tk, obtenemos R:

R = lim Rk = lim
k k

k ops vec frecuencia = lim k Tk

k 1 1000 = 432,43 MFLOPS k 15 + (10 + 10) + 2k 64

Si se desea implementar el fragmento de cdigo del enunciado en un procesador escalar, el cdigo podra ser as:

lf add lw slli bucle: lf multf sf addi sub bnez

f0, r1, r2, r2,

a ; Cargamos la constante a r0, r0 ; Inicializamos el ndice i=0 N ; Tamao del vector en elementos r2, #2 ; Multiplicamos por 4 para obtener el tamao del vector en ; bytes. Cada elemento ocupa 32 bits (4 bytes) f2, Y(r1) ; Cargamos X(i) f4, f0, f2 ; Multiplicamos Y(i) por a X(r1), f4 ; Guardamos el resultado r1, r1, #4 ; Pasamos al siguiente elemento r3, r1, r2 ; Comprobamos si hemos acabado r3, bucle ; Saltamos si quedan elementos

En el enunciado se afirma que el tiempo de ejecucin de este fragmento de cdigo est limitado por el tiempo que se tarda en acceder a los datos. Este tiempo depender de la ubicacin de los datos en la memoria principal. Como se nos indica que consideremos la ubicacin ms favorable, asumiremos que el primer dato de cada vector est alineado a una frontera de 32 Bytes, de forma que se ocupen el menor nmero de lneas, y que los vectores X e Y estn almacenados en posiciones de memoria tales que la correspondencia directa de la memoria cache los llevar a lneas diferentes. De esta forma slo se producirn fallos de cache cada vez que se acceda a una lnea diferente de la cache de datos. Como el procesador es de 32 bits, asumimos que cada elemento del vector ocupa 4 Bytes, por tanto, si cada vector tiene N = 1024 elementos, ocupar 4 KB de memoria. La ubicacin que hemos supuesto ms arriba implica que slo se cometer un fallo de cache cuando se intente leer o escribir un dato de una lnea que no haya sido llevada a cache, con lo que el nmero de fallos a la cache de datos en el acceso a un vector se puede calcular como:

f vector =

Tamao del vector 4 KB = = 128 Tamao de lnea 32 B

Adems de para leer los elementos del vector Y, como la cache realiza asignacin en escritura (writeallocate), cada vez que se intente escribir un elemento de X y no est en cache se traer una lnea de elementos de X. Por ltimo, tambin hay que cargar las variables a y N, que supondremos que estn las dos en otro lnea de cache, lo que aadir un fallo ms a los fallos que se produzcan en la manipulacin de los vectores. Por tanto, el total de fallos de la cache de datos es de:

f totales = 2 f vector + 1 = 257


Se accede a los 1024 elementos de cada vector ms a las variables a y N, por lo que el nmero total de accesos a datos es:

atotales = 2 1024 + 2 = 2050


Por tanto, las tasas de fallos y aciertos se pueden calcular como:

tfallos =

f totales 257 = = 0,125 atotales 2050

taciertos = 1 tfallos = 0,875

Suponiendo que se tarda 1 ciclo de CPU en acceder a la cache, el tiempo medio de acceso a un dato es:

Tacceso = taciertos Tcache + (1 taciertos ) (Tcache + Tmemoria ) = 0,875 1 + (1 0,875) (1 + 50) = 7,25 ns

Por lo que el tiempo total de acceso a datos sera, o lo que es lo mismo, el tiempo de ejecucin del programa en el procesador superescalar es de:

Tmemoria = Tacceso atotales = 7,25 2050 = 14862,5 ns


El tiempo de ejecucin en el procesador vectorial es de:

1024 (10 + 10) + 2 1024 = 2383 ns T1024 = 15 + 64


Con lo que se puede concluir que el programa tardaducho ms en el procesador superescalar debido al tiempo que se tarda en acceder a los datos.

Solucin al Problema 3:
Lo primero que vamos a hacer es escribir el programa usando predicados:
mult add cmp.ne lw add mult sub mult sw r1, r2, r3 r4, r5, r1 r4, r0 r6, dato r7, r4, r6 r2, r1, r7 r8, r1, r4 r1, r8, r2 resul, r1

p1 (p1) (p1) (p1)

Si empaquetamos estas instrucciones en instrucciones VLIW para el procesador descrito en el enunciado, respetando los tipos de instrucciones que se pueden emitir en cada slot y las latencias de las instrucciones, comprobamos que el programa tarda en ejecutarse 15 ciclos, de los cuales el procesador est cuatro ocioso debido a la alta latencia de la carga de memoria:
Ciclo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Slot 1
mult add cmp.ne lw r1, r2, r3 r4, r5, r1 r4, r0 r6, dato

Slot 2

p1 (p1)

sub

r8, r1, r4

(p1) (p1)

add mult mult sw

r7, r4, r6 r2, r1, r7 r1, r8, r2 resul, r1

Sera interesante que la carga se realizara al principio del programa para tratar de ocultar esta latencia. Como est vigilada por p1, se debe hacer especulativamente para ignorar las posibles excepciones que puedan ocurrir en su procesamiento, ya que si al calcular r4 toma el valor 0, la carga no debera haberse realizado y por tanto, no debera haber ocurrido ninguna excepcin. El cdigo para adelantar la carga es el siguiente:
lw.s mult add cmp.ne add mult sub r6, r1, r4, r4, r7, r2, r8, dato, repar r2, r3 r5, r1 r0 r4, r6 r1, r7 r1, r4

p1 (p1) (p1)

mult sw

r1, r8, r2 resul, r1

Y una vez colocado en forma de instrucciones VLIW, podemos comprobar que tarda 4 ciclos menos en ejecutarse, siempre que no falle la carga especulativa, o que no se use el valor envenenado en caso de que falle (si p1 toma el valor 0):
Ciclo 1 2 3 4 5 6 7 8 9 10 11 Slot 1
mult add cmp.ne add mult mult sw r1, r2, r3 r4, r5, r1 r4, r0 r7, r4, r6 r2, r1, r7 r1, r8, r2 resul, r1 lw.s

Slot 2
r6, dato, repar

p1 (p1) (p1)

sub

r8, r1, r4

Sin embargo, si la carga especulativa falla y adems p1 toma el valor 1 en la comparacin, r6 envenenara a r7, r7 a r2, y r2 a r1, por lo que al ejecutarse la instruccin de almacenamiento se intentara almacenar un resultado envenenado, permitiendo detectar al procesador que se produjo una excepcin en la carga especulativa. En este punto, el sistema saltara automticamente a la rutina de reparacin apuntada por repar, que tendra que recalcular todos los resultados envenenados hasta que se ha atendido la excepcin:
repar: lw add mult mult sw r6, dato r7, r4, r6 r2, r1, r7 r1, r8, r2 resul, r1

El cdigo VLIW para la rutina de reparacin es el siguiente:


Ciclo 1 2 3 4 5 6 7 8 9 10 11 Slot 1
lw r6, dato

Slot 2

add mult mult sw

r7, r4, r6 r2, r1, r7 r1, r8, r2 resul, r1

Como se puede observar, la rutina de reparacin tarda en ejecutarse otros 11 ciclos debido a la latencia de la carga de memoria, por lo que cuando haya un fallo de pgina el programa tardar en ejecutarse 22 ciclos, que es ms tiempo del que tardaba sin aplicar la optimizacin. Por tanto, esta optimizacin debera aplicarse slo si la probabilidad de que se produzca un fallo de pgina al cargar el dato es baja, o bien si la probabilidad de que r4 tome el valor 0 es pequea. Estas probabilidades se pueden estimar realizando algunas ejecuciones del programa sin optimizar y analizando su comportamiento.

Solucin al Problema 4:

El programa se ejecuta correctamente, ya que en cada iteracin se ejecutar la instruccin de almacenamiento que hay detrs del salto y el efecto que tendr ser simplemente el de almacenar la suma parcial acumulada en f0. Sin embargo, esta operacin, aunque no provoca que el resultado sea incorrecto, s que repercute en el tiempo de ejecucin del programa, ya que si el vector X tiene N elementos, se realizarn N 1 almacenamientos que consumen un tiempo de ejecucin que podra usarse para algo ms provechoso. Por ejemplo, una posible optimizacin podra ser la siguiente:
add subd bucle: ld subi multd addd bnez addi sd r1, f0, f2, r3, f6, f0, r3, r1, r0, r0 f0, f0 X(r1) r3, #8 f2, f4 f0, f6 bucle r1, #8 ; ; ; ; ; ; ; ; Inicializamos el ndice i a 0 Inicializamos el acumulador a 0 Cargamos X(i) Comprobamos si hemos acabado Multiplicamos X(i) por a (en f4) Acumulamos el resultado Saltamos si quedan elementos Incrementamos el contador del ndice

R, f0

; Guardamos el resultado

En este caso, la instruccin de despus del salto retardado se utiliza para incrementar el puntero al siguiente elemento de X, instruccin que hay que realizar de todas formas, con lo que el cuerpo del bucle pasa a tener una instruccin menos que antes. Adems, la instruccin de resta se ha colocado detrs la instruccin de carga para ocultar su retardo carga-uso. Para obtener la productividad del cauce primero tenemos que calcular cunto tiempo tarda en ejecutarse el programa para un vector de N elementos:
add subd ld subi multd addd bnez addi sd r1, r0, r0 f0, f0, f0 f2, X(r1) r3, r3, #8 f6, f2, f4 f0, f0, f6 r3, bucle r1, r1, #8 R, f0 1 IF 2 ID IF 3 EX ID IF 4 MEM EX ID IF 5 WB EX EX ID IF 6 MEM X X X 7 WB MEM EX ID IF 8 9 10 11 12 13 14 15 16 17

WB MEM EX ID IF

WB EX X X

EX X X

MEM EX ID IF

WB EX ID IF

MEM X X

WB EX ID MEM WB EX MEM

WB

Las partes sin sombrear de la figura indican el tiempo de inicializacin y finalizacin del programa, mientras que la parte que est sombreada es el tiempo que transcurre entre dos iteraciones del bucle, es decir, que tardamos 2 ciclos en comenzar la primera iteracin, que transcurren 9 ciclos entre el comienzo de una iteracin y el comienzo de la siguiente, y que tras la ltima iteracin se tardan 6 ciclos en acabar. Por tanto, el tiempo que tardara en ejecutarse el programa para procesar un vector de N elementos sera:

TN = 2 + 9 N + 6 = 9 N + 8
Sabiendo el tiempo de ejecucin, la productividad del cauce se puede expresar en trminos de resultados por ciclo o de instrucciones por ciclo:

WN =

N instrucciones 6 N + 3 = instr./ciclo Tiempo 9N + 8

WN =

N resultados N = resultados/ciclo Tiempo 9N + 8