ARQUITECTURA DE COMPUTADORES I Ingeniería Informática.

Septiembre de 2007
1. (2.5) Suponga un procesador superescalar en que se captan, decodifican, emiten y retiran hasta dos instrucciones por ciclo. La etapa de decodificación se realiza de forma ordenada, ya que es en esta etapa donde se introducen las instrucciones en un buffer de reordenamiento (ROB) que permite su finalización ordenada. Por el contrario, la emisión es desordenada y se implementa mediante estaciones de reserva individuales para cada unidad funcional. El procesador utiliza predicción dinámica de saltos con dos bits de historia. Para la primera ejecución de una instrucción de salto dada, el procesador predice saltar si la dirección de salto es hacia direcciones inferiores, y no saltar si la dirección es mayor. Las instrucciones de salto se procesan en la etapa de ejecución y consumen un ciclo en esa etapa (en el siguiente ciclo ya se tendría la dirección de salto correcta y se podría captar la instrucción correcta si la predicción de salto no hubiera sido correcta). Suponiendo una frecuencia de 2 GHz, que el cauce se encuentra inicialmente vacío, y que inicialmente r2=100000, para la siguiente secuencia de instrucciones: bucle: addd multd subd loop addd f1, f1, f6 f6, f2, f5 f5, f1, f3 r2, bucle f7, f1, f5 ; f1 = f1 + f6 ; f6 = f2 * f5 ; f5 = f1 – f3 ; f7 = f1 + f5

(a) ¿Cuánto tarda en procesarse la secuencia de instrucciones? (b) ¿Cuál es la velocidad pico del procesador? NOTA: La suma y la resta en coma flotante consumen dos ciclos de reloj y la multiplicación en coma flotante cuatro ciclos. Considere que no hay limitaciones en la capacidad de los buffers y en el número de unidades funcionales. Se supone que todos los registros tienen valores válidos previos. La instrucción loop decrementa el registro y salta si el valor del registro es distinto de cero. 2. (1.5) Suponga un procesador en el que todas las instrucciones pueden predicarse. Para establecer los valores de los predicados se utilizan instrucciones de comparación con el formato (p) p1, p2 cmp.cnd rx, ry

donde cnd es la condición que se comprueba entre rx y ry (lt, ge, eq, ne,…). Si la condición es verdadera, p1=1 y p2=0, y si es falsa, p1=0 y p2=1. La instrucción sólo se ejecuta si el valor del predicado p es 1 (habrá sido establecido por otra instrucción de comparación). (a) En estas condiciones, escriba la secuencia de instrucciones máquina que implementarían el siguiente código sin utilizar ninguna instrucción de salto: X = 0; if ((A≥B) and (B≥0)) then X = 1; else if ((B<0) and (A<B)) then X = 2; (b) Optimice el código anterior para un procesador VLIW con dos slots de emisión, en el que las instrucciones de comparación sólo pueden colocarse en el primero de ellos y las latencias de las operaciones son de 1 ciclo para las sumas, restas y comparaciones, de dos ciclos para las multiplicaciones y de tres ciclos para las cargas de memoria.

(2) no se anula nunca. for (i=0 . f4 . se ejecuta el siguiente bucle utilizando la técnica de troceado del vector (strip mining). indique si hay algún problema en la ejecución del código anterior si el salto: (1) se anula siempre. r1. almacenar f4 en a[i+2] . cargar f2 con a[i] . cargar f3 con a[i+1] . loop r5. calcule para el bucle: (a) El tiempo de ejecución para n=317 elementos. T317. cargar en r2 el número de iteraciones . f1 8(r1). r0.5) En un procesador vectorial. #1 r2. . c 0(r5). r2. se mejoren las prestaciones? 4. f4=a[i+1]+a[i] .3. f4. ¿qué podría decir respecto al tipo de procesador utilizado teniendo en cuenta el valor de CPI? (c) Si el programa anterior se implementa en un procesador segmentado con salto retardado y un hueco para instrucciones tras la instrucción de salto. a r2. 0(r1) f3. (4) se anula si no se salta. (a) Si se han tardado 200 milisegundos en ejecutar el programa. queda una iteración menos . (3) se anula si se salta. i++) a[i+2] = (a[i+1] + a[i]) * b. f4=f4*b . N f2. que el tiempo correspondiente a las operaciones escalares necesarias para preparar el ciclo es TBASE =10 ciclos. i<N . apuntar r1 donde empieza a[] . (b) El número de operaciones ejecutadas por unidad de tiempo para un vector de longitud infinita. ¿cuántos GFLOPS se han alcanzado? (Suponga que el producto y la suma en coma flotante tienen un coste similar). que el valor del tiempo de latencia de inicio es TLI=15 ciclos. b r1. (1. for i := 1 to n do Z(i) := a*Z(i) + b*X(i) + c*Y(i) Teniendo en cuenta que el tiempo de ejecución es TCV=63 ciclos para la secuencia de instrucciones vectoriales que implementan Z := a*Z + b*X + c*Y con 16 componentes. apuntar r5 donde empieza c[] . #4 r2. r0. f4 r1. (2. f2 f4. y que el tiempo correspondiente al control del bucle en el troceado del vector es TBUCLE=20 ciclos. si es posible. Rinf. f3.5) Suponga que en el siguiente programa N=108. c[0] = a[N+1]. almacenar f4 (a[N+1]) en c[0] (b) Si sabe que el procesador que se está utilizando es de 2 GHz. 4(r1) f4. Las instrucciones máquina que implementan este bucle en el procesador donde se ha ejecutado son: ld add ld loop: ld ld addf mulf sf add sub bnez add sf f1. cargar en f1 el valor de b . apuntar a a[i+1] . con una frecuencia de reloj de 500 MHz y con registros vectoriales de 16 componentes. (d) ¿Qué cambios haría en el código en el caso en que hay problemas y para que. a y c son dos vectores de números en coma flotante. y b es un escalar en coma flotante.

que el resto de iteraciones terminan cada MLM = 4 ciclos. y que la última instrucción termina 3 ciclos después de la última iteración del bucle. bucle addd f1. Si nos fijamos en el instante de tiempo en el que se retira la última instrucción del bucle en cada iteración. f5 subd f5. instrucción addd f1. f2. Para determinar estos dos parámetros es necesario desarrollar una traza de la ejecución del programa en la que se tengan en cuenta las características del procesador. f1. f2. f5 subd f5. Teniendo en cuenta las etapas del cauce. f3 loop r2. f3 loop r2. Por tanto. una vez que se identifique el salto. Instrucción addd f1. el resto de iteraciones irán terminando cada MLM ciclos. Riesgos de control al procesar el salto del bucle (marcados con flechas verdes). f5 1 IF IF 2 3 4 5 6 ROB EX EX ROB X X 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ID ISS EX EX ID ISS EX EX IF ID IF ID ISS EX IF X X IF X X IF ID IF ID IF IF WB EX ROB WB EX ROB WB WB WB X ROB EX EX ROB X X X X X X ISS EX EX ISS EX EX ID ISS ID ISS EX IF ID IF ID IF ID IF ID ISS IF ID IF ID IF IF WB WB EX ROB WB EX ROB WB WB ISS EX EX ROB WB ISS EX EX EX EX ROB WB ISS EX EX ROB WB ROB WB X X X X X X X WB X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X IF ID ISS EX EX ROB EX ISS ID ID IF IF WB WB X WB X WB X X WB WB 10 4 4 3 La primera vez que se capta el salto no se puede usar el predictor dinámico porque no existe ninguna entrada en el BTB del procesador para él. f1. se incluirá una entrada en el BTB para que la siguiente vez que se capte se pueda usar el predictor dinámico. A continuación se simula la ejecución del bucle haciendo tres iteraciones. f6 multd f6. el predictor estático tendrá una penalización de 1 ciclo para los saltos acertados. por lo que no hay penalización en caso de acertar.Solución al problema 1: Para responder al primer apartado es necesario tener en cuenta que el programa se ejecutará en un procesador superescalar en el que se solaparán las iteraciones del bucle. f6 multd f6. Esto ocurrirá en el resto de iteraciones menos en la última. f2. Por tanto. bucle addd f1. y se anularán las dos instrucciones que se captaron erróneamente tras el salto. f2. f1. f1. una vez terminada la primera iteración tras un tiempo TLI. se anulan todas las instrucciones captadas especulativamente y se comienza a captar desde la dirección correcta para terminar la ejecución del programa. f5 addd f7. f1. f6 multd f6. f3 loop r2. f2. en la que el predictor fallará y tendremos una penalización de 3 ciclos hasta captar la siguiente instrucción al salto. f1. f1. f5 subd f5. f1. f3 loop r2. A partir de la segunda iteración. por tanto para un bucle de n iteraciones tenemos: T(n) = TLI + MLM(n – 1) + Tfinal = 10 + 4(n – 1) + 3 = 4n + 9 ciclos Teniendo en cuenta que el registro r2 = 100000 y que la frecuencia de reloj es de 2 GHz. podemos comprobar que la primera iteración tarda en concluir un tiempo TLI = 10 ciclos. en la etapa de decodificación. se usará un predictor estático que predecirá saltar (el salto es hacia atrás). cada vez que se capta el salto se usa el predictor dinámico. bucle addd f1. bucle addd f7. el tiempo de ejecución es de: . f5 Sig. Riesgos estructurales (marcados con flechas azules). f1. f1. ya que es en la etapa de ejecución en la que se comprueba la corrección de la predicción. f6 multd f6. Una vez que se comprueba que falló la predicción. A la hora de realizar esta traza tenemos que tener cuidado con los riesgos que ocurrirán en la ejecución del programa: • • • Riesgos RAW entre datos dentro de una iteración y también entre iteraciones consecutivas (marcados con flechas rojas). f5 subd f5. f1. f6 multd f6.

#1 r3. el programa realiza un total de 2×108 operaciones en coma flotante en 200×10-3 segundos. r0. r3 = 1 r3. r0. X Solución al problema 3: Para responder al primer apartado hay que calcular el número de operaciones en coma flotante que se pueden realizar por segundo. podemos obtener el número medio de ciclos que tarda . A .lt r1. r0.lt cmp. p2 p2 p2 cmp. B (p1) (p2) (p2) (p1) (p2) addi addi sw r3. sólo nos queda optimizarlo para la arquitectura VLIW propuesta en el enunciado: Slot 1 lw add p1. r2 r2. r0.T (100000 ) = 4 × 10 5 + 9 ciclos ≈ 200 microsegundos 2 × 10 9 ciclos s Y como el procesador puede completar hasta 2 instrucciones por ciclo. r3 = 0 r1. B . p2 p2 p2 cmp.ge cmp. #1 . r2 = B r3. r0 r2.lt addi addi sw r1. r0 r2. r1 = A r2. X = r3 Fin Una vez escrito el código. r0 r1. r0 r1. y como se realizan 108 iteraciones.ge cmp. r2 . #2 r3. #2 . el programa ejecuta un número de instrucciones de NI = 3 + 8×108 + 2 Y como sabemos que el tiempo de ejecución es T = NI × CPI × TClk.lt cmp. r2 Slot 2 lw r2. r3 = 2 r3. r0 . r0. r0 r1. A >= B? . En cada iteración del bucle se realiza una suma y una multiplicación. A r3. por tanto. p2 p1. se alcanzan R10 = 8 2 × 108 operaciones = 1GFLOP 200 × 10 −3 segundos Teniendo en cuenta el código ensamblador del enunciado.ge cmp. p2 p1. B < 0? . A < B? r3. r0. su velocidad pico es de: R pico = 2 instrucciones ciclo × 2 ⋅ 10 9 ciclos s = 4 × 10 9 instruccio nes s Solución al problema 2: El organigrama y el código secuencial que implementa la secuencia de código del enunciado es el siguiente: Inicio X←0 Si p1 Si p1 X←1 Si p2 X←2 p2 A<B No B≥0 No p2 Si B<0 No No A≥B lw lw add (p1) (p2) (p2) (p1) (p2) p1. B >= 0? . r2 r2.ge cmp. X .

r1. r0. según explote el paralelismo dinámica o estáticamente. Solución al problema 4: Sabemos que en un procesador vectorial.5 NI × TClk 5 + 8 × 108 ( ( ) ( ) ) Por tanto. f4. f1 sf 8(r1). f2 mulf f4. f2 mulf f4. loop nop add r5. c sf 0(r5). el procesador puede terminar 2 instrucciones por ciclo. r0. f1 sf 8(r1). b add r1. #1 bnez r2. f2 mulf f4. (3) Si la siguiente instrucción al salto se anula sólo si se toma el salto. #4 sub r2. como dicha instrucción afecta a r5. con lo que se puede concluir que el procesador es superescalar o VLIW. #4 sub r2. r0. #1 bnez r2. f3. f4 Se anula si no se salta ld f1. f4. a ld r2. puede que sea necesario cambiar el código del programa para asegurar su correcto funcionamiento: (1) En el caso en el que la instrucción que entra en el cauce tras el salto se anule siempre. el programa podría fallar si dicha instrucción afecta a los registros que se usan en el bucle. f4 add r1. A continuación se muestran las modificaciones que serían necesarias para optimizar el programa en cada caso: Se anula siempre ld f1. f4. r0. r0. N ld f2. aunque ejecutaría la instrucción siguiente al salto en todas las iteraciones. N loop: ld f2. f4 add r1. que no se usa en el bucle. r2. En este ejemplo concreto. Pero en este ejemplo concreto el programa funcionaría correctamente si el bucle itera más de una vez. f3. r0. el programa se puede dejar tal y como está. f4 add r1. #1 bnez r2. b add r1. 0(r1) ld f3. 0(r1) ld f3. #4 add r5. c sf 0(r5). c sf 0(r5). el programa funcionaría correctamente. f2 mulf f4. f3. Dependiendo de la implementación del salto retardado. f3. a ld r2. 4(r1) addf f4. #4 sub r2. N loop: ld f2. b add r1. ya que se fijaría en r5 el valor del puntero donde empieza la matriz c en todas las iteraciones menos en la última. f1 sf 8(r1).en ejecutarse una instrucción: CPI = T 200 × 10 -3 × 2 × 109 = ≈ 0. (4) Por último. N loop: ld f2. r2. 0(r1) ld f3. #1 bnez r2. r1. loop add r1. 4(r1) addf f4. el programa podría fallar si dicha instrucción afecta a los registros que se usan en el bucle. 0(r1) add r5. f1 sf 8(r1). loop ld f2. b add r1. ya que sólo se ejecutará cuando se termine el bucle. f4 sub r2. 4(r1) addf f4. el tiempo para procesar una operación completa vectorial (para los 16 elementos que caben en un registro vectorial) es: TCV = TLI + MVL · TPC Por lo tanto. r0. (2) Si la instrucción siguiente al salto no se anula nunca. desperdiciando un tiempo de computación que podría usarse en algún cálculo útil. sería necesario insertar una instrucción NOP entre el salto y la suma. r0. también sería conveniente modificar el programa para ejecutar la instrucción siguiente al salta una sola vez tras la última iteración y aprovechar el spot del salto para realizar algún cálculo útil. 0(r1) loop: ld f3. a ld r2. ocurre igual que en el caso (2). r1. f4 No se anula nunca ld f1. por lo que en el almacenamiento se accedería a la dirección correcta. c sf 0(r5). En este caso. f4 Se anula si se salta ld f1. f4 Cualquiera de las soluciones (2) y (4) son intercambiables para ambos casos. en la que no se debe saltar. r1. si la siguiente instrucción al salto se anula sólo si no se salta. 4(r1) addf f4. se anularía la siguiente instrucción al salto y la operación de almacenamiento final no accedería a la dirección correcta. ya que en la última iteración. f4. r2. r2. loop add r5. podemos obtener el tiempo por componente de la secuencia de instrucciones vectoriales como: . a ld r2.

TPC = TCV − TLI 63 − 15 = =3 MVL 16 Una vez obtenido el tiempo por componente. el máximo rendimiento se obtendrá cuando el tamaño del vector tienda a infinito.93 MFLOPS 35 +3 16 . el tiempo para procesar 317 elementos sería de: ⎡ 317 ⎤ (15 + 20) + 317 ⋅ 3 = 1661 ciclos = 1661 6 segundos T317 = 10 + ⎢ ⎥ 500 × 10 ⎢ 16 ⎥ El rendimiento de un cauce vectorial se obtiene mediante la siguiente expresión: Rk = k × operacione s vectorial es = Tk 5k × 500 ⋅ 10 6 25k × 10 8 = ⎡k⎤ ⎡k⎤ 10 + ⎢ ⎥ (15 + 20 ) + 3k 10 + 35⎢ ⎥ + 3k 16 ⎢ ⎥ ⎢ 16 ⎥ Por tanto. R∞ = lim Rk = k →∞ 25 × 108 = 481. el tiempo de ejecución del programa se obtiene mediante la siguiente expresión: ⎡ k ⎤ Tk = TBASE + ⎢ ⎥ (TLI + TBUCLE ) + k ⋅ TPC ⎢ MVL ⎥ Por tanto. es decir.