Está en la página 1de 6

ARQUITECTURA DE COMPUTADORES I

Examen de Septiembre (14-9-2004)

1. (1.5 puntos) En un procesador vectorial a 1 GHz, con registros vectoriales de 64 componentes, tres unidades de
carga/almacenamiento de memoria (LV/SV), un sumador y un multiplicador, se ejecuta el bucle:

for i:=1 to 342 do Z(i):= Z(i)+X(i)*Y(i)

Determine el valor de R∞ teniendo en cuenta que el procesador puede encadenar y solapar los cauces y que cada uno de
esos cauces, por separado, puede terminar un componente por ciclo.
(Nota: TLI(Mult) = 16 ciclos; TLI(Suma) = 8 ciclos; TLI(LV/SV) = 8 ciclos; TBASE = 8 ciclos; TBUCLE = 10 ciclos).

2. (1.5 puntos) En un procesador VLIW cuyas instrucciones pueden codificar tres operaciones (tres campos o slots en cada
instrucción VLIW), todas las operaciones pueden predicarse. Para establecer los valores de los predicados se utilizan
instrucciones de comparación (cmp) con el formato (p) p1[, p2] cmp.cnd x,y donde cnd es la condición que se
comprueba entre x e y (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
operación sólo se ejecuta si el predicado p=1 (habrá sido establecido por otra instrucción de comparación).
Indique cómo se escribiría la sentencia

for i=1 to 2 do
if (X[i] > 2) then {Y[i]=X[i]; X[i]=3*X[i];} else if (X[i]>0) then {Y[i]= –X[i]; X[i]=5*X[i];}

sin ninguna operación de salto y con el mínimo número de instrucciones VLIW, teniendo en cuenta que las instrucciones
de comparación sólo pueden aparecer en el primer campo o slot de la instrucción VLIW (el resto de las instrucciones
pueden aparecer en cualquier campo). Considere que dispone del número de unidades funcionales que necesite en cada
momento.

3. (2 puntos) Suponga un procesador superescalar en el que se decodifican dos instrucciones por ciclo, se emiten tres
instrucciones por ciclo como máximo, y se retiran hasta dos instrucciones por ciclo. La emisión es desordenada y no
alineada y se realiza directamente a las unidades de ejecución, es decir, que el procesador no dispone de estaciones de
reserva. La ejecución también es desordenada, y para permitir la finalización ordenada, se dispone de un buffer de reorden
(ROB) en el que se introducen las instrucciones una vez decodificadas y del que se retiran en orden una vez que ha
finalizado.

Indique las dependencias entre las instrucciones, los ciclos en los que se emiten para su ejecución y cómo evolucionaría en
buffer de reorden hasta que se hayan retirado todas las instrucciones de la siguiente secuencia almacenada en la cola de
instrucciones captadas:

multd f1, f1, f5 ; f1 = f1 * f5


addd f2, f2, f5 ; f2 = f2 + f5
addd f4, f1, f2 ; f4 = f1 + f2
addd f6, f1, f5 ; f6 = f1 + f5
multd f5, f2, f2 ; f5 = f2 * f2
subd f6, f2, f1 ; f6 = f2 – f1

Suponiendo una frecuencia de 2 GHz, ¿cuánto tarda en procesarse la secuencia de instrucciones? ¿Cuál es la velocidad
pico del procesador?
Nota: La suma y la resta consumen 1 ciclo de reloj y la multiplicación tres ciclos. Considere que no hay limitaciones en la
capacidad de los buffers ni en el número de unidades funcionales. Se supone que f1, f2 y f5 tienen valores previos.

4. (1.5 puntos) Se han encontrado dos posibles alternativas para la ejecución de una función F en un cauce con 4 etapas
S1, S2, S3 y S4. La alternativa 1 visita las etapas según la secuencia S1 S3 S1 S3 S2 S3 S4, y la alternativa 2 en el orden
S1 S2 S3 S4 S2 S3. (A) ¿Cuál de las dos alternativas permite ejecutar un número mayor de funciones por unidad de
tiempo? Demuestre razonadamente su respuesta. (B) Obtenga además la ganancia en velocidad que ofrece cada una de las
alternativas con respecto a su ejecución sin cauce para 500 operaciones, teniendo en cuenta que sin cauce la función
requiere un tiempo de 15 ns; que las etapas del cauce suponen unos tiempos de ejecución de: 4 ns para S1, 5 ns para S2,
2 ns para S3 y 4 ns para S4; y que los registros de acoplo entre etapas introducen un retardo de 0.25 ns.

5. (1.5 puntos) En un computador con tres procesadores, A, B y C, cada uno dispone de dos niveles de cache, L1 y L2,
con política de actualización 'write-back' y protocolo MESI, con 'write-once', para mantener la coherencia de cache (sin
'allocate-on-write' en L1). Suponga una dirección de memoria no contenida en las memorias caches, e indique los estados
por los que va pasando la correspondiente línea en las caches L1 y L2 de cada procesador tras cada uno de los siguientes
eventos: (1) Escritura generada por el procesador A; (2) Lectura generada por el procesador B; (3) Escritura generada por
el procesador C; (4) Escritura generada por el procesador B; (5) Lectura generada por el procesador A; (6) Escritura
generada por el procesador A; (7) Lectura generada por el procesador C.
Solución al Problema 1:
Dado que el tamaño de los registros vectoriales del procesador propuesto en el problema es MVL = 64 y que el vector que deseamos
procesar tiene un tamaño n = 342 mayor, tendremos que aplicar la técnica de strip-mining para trocear el vector y procesarlo
iterativamente. El compilador realizará un cambio al código 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++)
Z(i):= Z(i)+X(i)*Y(i);
low += VL;
VL = MVL;
}

Al traducir este código a ensamblador, el bucle que se encuentra sombreado se cambiará por instrucciones vectoriales y el resto de
instrucciones permanecerán tal y como están.

Dado que R∞ se define como

k × operaciones vectoriales × frecuencia


R∞ = lim R k = lim
k →∞ k →∞ Tk

el primer paso consistirá en estimar el tiempo Tk. Para ello, debemos determinar las instrucciones vectoriales que se ejecutarán dentro
del bucle interno y la forma en que se solaparán y encadenarán. Dichas instrucciones serán tres cargas vectoriales de X, Y, y Z, una
multiplicación, una suma y un almacenamiento del resultado en Z. El diagrama de tiempos de estas instrucciones es el siguiente:

TLI=8 LV VX, RX

TLI=8 LV VY, RY

TLI=8 LV VZ, RZ

TLI=16 MULT V1, VX, VY

TLI=8 ADD VZ, VZ, V1

TLI=8 SV RZ, VZ

8 64 64 8

Como sólo tenemos tres unidades de carga/almacenamiento, la instrucción SV debe esperar a que terminen las instrucciones LV, por
tanto, tenemos que el tiempo por componente es TPC = 2 y que el tiempo de latencia inicial TLI = 8 + 8 = 16, ya que la multiplicación y
la suma han quedado solapadas 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 ⎤
Tk = TBASE + ⎢ (TLI + TBUCLE ) + k ⋅ TPC = 8 + ⎡⎢ k ⎤⎥(16 + 10) + 2·k ciclos
⎢ MLV ⎥⎥ ⎢ 64 ⎥

Una vez obtenido Tk, obtenemos R∞:

k × ops vec × frecuencia k × 2 × 1000 2000k


R∞ = lim Rk = lim = lim = lim = 831,17 MFLOPS
k →∞ k →∞ k →∞ ⎡k ⎤ k →∞ ⎡k ⎤
8 + ⎢ ⎥ (16 + 10) + 2·k 8 + ⎢ ⎥(26) + 2·k
Tk
⎢ 64 ⎥ ⎢ 64 ⎥
Solución al Problema 2:
Como en el enunciado nos indican que la secuencia de instrucciones debe quedar sin ningún salto, debemos desenrollar el bucle y
predicar las instrucciones que contiene en su interior. A continuación se muestran el organigrama del programa una vez que se ha
desenrollado el bucle y se han predicado las instrucciones y su código en ensamblador derivado.

addi r13, r0, #3 ; r13 ← 3


addi r15, r0, #5 ; r15 ← 5

Inicio lw r1, X(r0) ; r1 ← X[1]


subi r2, r1, #2 ; r2 ← X[1] – 2
p1, p2 cmp.gt r2, r0 ; p1 ← 1 si X[1] > 2
(p1) Si No (p2)
X[1] > 2 p3 cmp.ne r0, r0 ; p3 ← 0
(p1) sw r1, Y(r0) ; Y[1] ← X[1]
Y[1] ← X[1] (p3) Si No (p1) mult r3, r1, r13 ; r3 ← 3*X[1]
X[1] > 0
X[1] ← 3*X[1] (p1) sw r3, X(r0) ; X[1] ← 3*X[1]
Y[1] ← –X[1] (p2) p3 cmp.gt r1, r0 ; p3 ← 1 si X[1] > 0
X[1] ← 5*X[1] (p3) sub r4, r0, r1 ; r4 ← –X[1]
(p3) sw r4, Y(r0) ; Y[1] ← –X[1]
(p3) mult r5, r1, r15 ; r5 ← 5*X[1]
(p3) sw r5, X(r0) ; X[1] ← 5*X[1]
(p4) Si No (p5)
X[2] > 2
lw r6, X+4(r0) ; r6 ← X[2]
Y[2] ← X[2] (p6) Si No subi r7, r6, #2 ; r7 ← X[2] – 2
X[2] > 0
X[2] ← 3*X[2] p4, p5 cmp.gt r7, r0 ; p4 ← 1 si X[2] > 2
Y[2] ← –X[2] p6 cmp.ne r0, r0 ; p6 ← 0
X[2] ← 5*X[2] (p4) sw r6, Y+4(r0) ; Y[2] ← X[2]
(p4) mult r8, r6, r13 ; r8 ← 3*X[2]
(p4) sw r8, X+4(r0) ; X[2] ← 3*X[2]
(p5) p6 cmp.gt r6, r0 ; p6 ← 1 si X[2] > 0
Fin (p6) sub r9, r0, r6 ; r9 ← –X[2]
(p6) sw r9, Y+4(r0) ; Y[2] ← –X[2]
(p6) mult r10, r6, r15 ; r10 ← 5*X[2]
(p6) sw r10, X+4(r0) ; X[2] ← 5*X[2]

Tras desenrollar e introducir las operaciones con predicados, sólo nos queda reorganizar el código respetando las dependencias de datos
para construir las instrucciones VLIW:

Slot 1 Slot 2 Slot 3


p3 cmp.ne r0, r0 lw r1, X(r0) lw r6, X+4(r0)
p6 cmp.ne r0, r0 subi r2, r1, #2 subi r7, r6, #2
p1, p2 cmp.gt r2, r0 addi r13, r0, #3 addi r15, r0, #5
p4, p5 cmp.gt r7, r0 (p1) sw r1, Y(r0) (p1) mult r3, r1, r13
(p2) p3 cmp.gt r1, r0 (p4) sw r6, Y+4(r0) (p4) mult r8, r6, r13
(p5) p6 cmp.gt r6, r0 (p1) sw r3, X(r0) (p4) sw r8, X+4(r0)
(p3) sub r4, r0, r1 (p6) sub r9, r0, r6 (p3) mult r5, r1, r15
(p3) sw r4, Y(r0) (p6) sw r9, Y+4(r0) (p6) mult r10, r6, r15
(p3) sw r5, X(r0) (p6) sw r10, X+4(r0)
Solución al Problema 3:
Ya que el procesador no dispone de estaciones de reserva, la lógica de emisión tiene que esperar a que los operandos le sean facilitados
por la lógica de bypass, por tanto, las dependencias RAW afectarán al orden de emisión de las instrucciones. Existen las siguientes
dependencias RAW:

• La instrucción 3 depende de f1 producido por la instrucción 1 y f2 producido por la instrucción 2.


• La instrucción 4 depende de f1 producido por la instrucción 1.
• La instrucción 5 depende de f2 producido por la instrucción 2.
• La instrucción 6 depende de f1 producido por la instrucción 1 y f2 producido por la instrucción 2.

Teniendo en cuenta estas dependencias, las instrucciones se ejecutarían como se muestra en la siguiente figura:

Instrucción / Ciclo 1 2 3 4 5 6 7 8
(1) multd f1, f1, f5 ID ISS EX EX EX WB
(2) addd f2, f2, f5 ID ISS EX WB
(3) addd f4, f1, f2 ID ISS EX WB
(4) addd f6, f1, f5 ID ISS EX WB
(5) multd f5, f2, f2 ID ISS EX EX EX WB
(6) subd f6, f1, f2 ID ISS EX WB

A continuación pasamos a describir la evolución del buffer de reorden:

Ciclo 1: # Cod. Op. Dest. Result. Ok


• Se decodifican las instrucciones 1 y 2 y se 1 multd f1 ? 0
introducen en el ROB 2 addd f2 ? 0

# Cod. Op. Dest. Result. Ok


Ciclo 2: 1 multd f1 ? 0
• Se decodifican las instrucciones 3 y 4 y se 2 addd f2 ? 0
introducen en el ROB 3 addd f4 ? 0
4 addd f6 ? 0

# Cod. Op. Dest. Result. Ok


1 multd f1 ? 0
Ciclo 3:
2 addd f2 f2+f5 1
• Finaliza la instrucción 2
3 addd f4 ? 0
• Se decodifican las instrucciones 5 y 6 y se
4 addd f6 ? 0
introducen en el ROB
5 multd f5 ? 0
6 subd f6 ? 0

# Cod. Op. Dest. Result. Ok


1 multd f1 f1*f5 1
2 addd f2 f2+f5 1
Ciclo 5:
3 addd f4 ? 0
• Finaliza la instrucción 1
4 addd f6 ? 0
5 multd f5 ? 0
6 subd f6 ? 0

# Cod. Op. Dest. Result. Ok


Ciclo 6: 3 addd f4 f1+f2 1
• Se retiran las instrucciones 1 y 2 4 addd f6 f1+f5 1
• Finalizan las instrucciones 3, 4 y 6 5 multd f5 ? 0
6 subd f6 f1–f2 1

Ciclo 7: # Cod. Op. Dest. Result. Ok


• Se retiran las instrucciones 3 y 4 5 multd f5 f2*f2 1
• Finaliza la instrucción 5 6 subd f6 f1–f2 1
Ciclo 8:
# Cod. Op. Dest. Result. Ok
• Se retiran las instrucciones 5 y 6

Si el procesador funciona a 2 GHz, el tiempo de procesamiento sería

8 ciclos * 5×10–10 s/ciclo = 4×10–9 s = 4 ns

Para la calcular la velocidad pico, como sólo se pueden retirar dos instrucciones por ciclo, suponiendo que no hubiera atascos en el
cauce se podrían ejecutar 2 instrucciones por ciclo

2 instr./ciclo * 2×109 ciclos/s = 4 GIPS


Solución al Problema 4:
El primer paso para responder al primer apartado es calcular la tabla de reservas para cada una de las dos alternativas:

Alternativa 1 Alternativa 2

1 2 3 4 5 6 7 1 2 3 4 5 6
S1 X X S1 X
S2 X S2 X X
S3 X X X S3 X X
S4 X S4 X

Una vez calculadas las tablas de reservas es fácil obtener las latencias prohibidas y los vectores de colisiones de cada una de las
alternativas:

F1 = {2,4} C1 = (1010) F2 = {3} C2 = (100)

Para calcular determinar qué alternativa tiene la máxima productividad, realizamos un diagrama de estados a partir de cada vector de
colisiones:

Alternativa 1 Alternativa 2
3
1010 100
3 1 2 4

1
5
1
1011 1111 101 110 111
3 2

La mínima latencia mínima de cada alternativa es:

MLM1 = 3 MLM2 = 2

Para ver qué alternativa es capaz de ejecutar más operaciones por unidad de tiempo basta con calcular la productividad máxima de cada
una de ellas. La productividad máxima se define como:

n n 1
Wmax = lim W (n ) = lim = lim =
n →∞ n →∞ T (n ) n →∞ TLI + MLM ( n − 1) MLM

Para cada una de las alternativas tenemos que:

1 1 1 1
W1 max = = = 0,3 W 2 max = = = 0,5
MLM 1 3 MLM 2 2

con lo que podemos concluir que la segunda alternativa es mejor que la primera.

Para responder a la segunda cuestión, debemos calcular tanto el tiempo secuencial como el de cada una de las alternativas para realizar
500 operaciones. En el caso secuencial tenemos que:

TSec(500) = 500 operaciones · 15 ns/operación = 7500 ns

Y en el caso paralelo, el tiempo de ejecución se define como:

T ( n ) = Tclock ·(TLI + MLM ( n − 1) )

El tiempo ciclo del reloj se puede obtener como:

Tclock = máx{TS1, TS2, TS3, TS4} + Tacoplo = máx {4, 5, 2, 4} + 0,25 = 5 + 0,25 = 5,25 ns

Por tanto, la ganancia en velocidad de cada una de las alternativas respecto al caso secuencial es de:

T Sec (500) 7500 T Sec (500) 7500


S 1 (500) = = = 0,95 S 2 (500) = = = 1,42
T1 (500) 5,25(7 + 3(500 − 1)) T2 (500) 5,25(6 + 2(500 − 1))
Solución al Problema 5:
A continuación se detallan los estados por los que irán pasando las líneas de las caches L1 y L2 del procesador con la secuencia de
accesos descrita en el enunciado del problema:

Acceso 1: Escritura generada por el procesador A:


Proc. Estado de la línea en la cache L1 Estado de la línea en la cache L2
La línea sigue estando en ESTADO I, ya que inicialmente no La línea se carga con el bloque de memoria principal que se
A se encontraba en L1 y L1 es de tipo “no-allocate on write”. desea escribir, se modifica y pasa a estar en ESTADO M.
La línea sigue estando en ESTADO I, ya que inicialmente no La línea sigue estando en ESTADO I, ya que inicialmente no
B se encontraba en L1. se encontraba en L2.
La línea sigue estando en ESTADO I, ya que inicialmente no La línea sigue estando en ESTADO I, ya que inicialmente no
C se encontraba en L1. se encontraba en L2.

Acceso 2: Lectura generada por el procesador B:


Proc. Estado de la línea en la cache L1 Estado de la línea en la cache L2
La línea sigue estando en ESTADO I. Se copia el contenido de la línea en memoria principal para
A que los demás procesadores puedan tener acceso a los datos
modificados y se pasa al ESTADO S.
La línea se trae de L2 a L1 y pasa a estar en ESTADO S en La línea se carga con el bloque de memoria principal que se
B L1, ya que se está compartiendo con L2. desea leer y pasa a estar en ESTADO S.
La línea sigue estando en ESTADO I, ya que inicialmente no La línea sigue estando en ESTADO I, ya que inicialmente no
C se encontraba en L1. se encontraba en L2.

Acceso 3: Escritura generada por el procesador C:


Proc. Estado de la línea en la cache L1 Estado de la línea en la cache L2
La línea sigue estando en ESTADO I. La línea pasa al ESTADO I, ya que será modificada por el
A procesador C.
La línea pasa al ESTADO I, ya que será modificada por el La línea pasa al ESTADO I, ya que será modificada por el
B procesador C. procesador C.
La línea sigue estando en ESTADO I, ya que L1 es de tipo La línea se carga con el bloque de memoria principal que se
C “no-allocate on write”. desea escribir, se modifica y pasa a estar en ESTADO M.

Acceso 4: Escritura generada por el procesador B:


Proc. Estado de la línea en la cache L1 Estado de la línea en la cache L2
A La línea sigue estando en ESTADO I. La línea sigue estando en ESTADO I.
La línea sigue estando en ESTADO I, ya que L1 es de tipo La línea se carga con el bloque de memoria principal que se
B “no-allocate on write”. desea escribir, se modifica y pasa a estar en ESTADO M.
Se copia el contenido de la línea en memoria principal para
C La línea sigue estando en ESTADO I. que los demás procesadores puedan tener acceso a los datos
modificados y se pasa al ESTADO I.

Acceso 5: Lectura generada por el procesador A:


Proc. Estado de la línea en la cache L1 Estado de la línea en la cache L2
La línea se trae de L2 a L1 y pasa a estar en ESTADO S en La línea se carga con el bloque de memoria principal que se
A L1, ya que se está compartiendo con L2. desea leer y pasa a estar en ESTADO S.
Se copia el contenido de la línea en memoria principal para
B La línea sigue estando en ESTADO I. que los demás procesadores puedan tener acceso a los datos
modificados y se pasa al ESTADO S.
C La línea sigue estando en ESTADO I. La línea sigue estando en ESTADO I.

Acceso 6: Escritura generada por el procesador A:


Proc. Estado de la línea en la cache L1 Estado de la línea en la cache L2
También se modifica la línea en L2 (write once) para cambiar
A La línea se modifica y pasa a estar en ESTADO E. su estado a ESTADO M, de forma que de cara al bus el resto
de procesadores se enteren de que se ha modificado.
La línea pasa al ESTADO I, ya que será modificada por el
B La línea sigue estando en ESTADO I.
procesador A.
C La línea sigue estando en ESTADO I. La línea sigue estando en ESTADO I.

Acceso 7: Lectura generada por el procesador C:


Proc. Estado de la línea en la cache L1 Estado de la línea en la cache L2
Se copia el contenido de la línea en memoria principal para
La línea pasa a estar en ESTADO S, ya que se va a compartir
A que los demás procesadores puedan tener acceso a los datos
con el procesador C.
modificados y se pasa al ESTADO S.
B La línea sigue estando en ESTADO I. La línea sigue estando en ESTADO I.
La línea se trae de L2 a L1 y pasa a estar en ESTADO S en La línea se carga con el bloque de memoria principal que se
C L1, ya que se está compartiendo con L2. desea leer y pasa a estar en ESTADO S.

También podría gustarte