Professional Documents
Culture Documents
Segmentación de Cauce
Torig n n T (1)
y en el caso segmentado
donde TLI es el tiempo de latencia inicial, es decir el tiempo que tarda en procesarse la
primera de las n funciones. Como se puede ver, una vez que ha terminado de procesarse la
primera de las funciones a procesar, dado que todas las etapas del cauce estarían ocupadas en
una de las restantes funciones, esas funciones van terminando una a una transcurrido
únicamente un intervalo de tiempo t. El valor del TLI será igual al número de etapas del
cauce, k, multiplicado por el intervalo de tiempo, t (TLI = k×t). Es decir, la ganancia de
velocidad que se consigue con la segmentación de cauce en k etapas es igual a:
Torig n n T n T
S k n (3)
Tseg n TLI n 1 t k n 1 t
Como se puede ver, en el límite, cuando el número de funciones procesadas es lo
suficientemente elevado como para que TLI sea despreciable frente a (n – 1) × t (y por
supuesto, además 1 sería despreciable frente a n), la ganancia de velocidad que se obtiene
tiende a:
T
S max lim Sk n (4)
n t
Cuanto menor sea el tiempo de una etapa del cauce, t, frente al tiempo total de
procesamiento no segmentado de la función, T, mayor será la ganancia de velocidad que se
podría obtener cuando se procesa un número elevado de funciones de forma continua. En el
caso ideal en el que el tiempo no segmentado de la función sea igual a la suma del tiempo de
las etapas, es decir, T = k × t, entonces, sustituyendo en la expresión anterior, Smax = k. Es
decir, la máxima ganancia alcanzable sería igual al número de etapas del cauce. Al realizar un
diseño segmentado de un cauce, los tiempos de procesamiento de las etapas pueden tener
distintos de procesamiento, t1, t2,…., tk. La más lenta de esas etapas es la que determinará el
ritmo a la que las funciones van pasando de etapa a etapa, es el cuello de botella que
determina el tiempo de retardo que tendrán todas las etapas. Además, para acoplar una etapa
con la siguiente se introducen registros de acoplo donde se almacena el resultado de una
etapa y desde lo leerá la etapa siguiente. Si denominamos d al retardo que introduce el
registro de acoplo entre dos etapas, tendremos que el tiempo de etapa en el cauce, t, será
igual a
n n n
Wk n (6)
Tseg n TLI n 1 t k n 1 t
1
Wmax lim Wk n (7)
n t
y, por lo tanto, la productividad máxima de un cauce es la inversa del tiempo de etapa del
cauce. Cuanto más pequeño sea dicho tiempo, mayor será la máxima productividad del
cauce. Así, a medida que el diseño de un cauce tiene más etapas (con tiempos más pequeños)
mayor es la productividad máxima posible (tal y como ocurría con la ganancia máxima).
Un procesador segmentado consta de varias etapas correspondientes a las distintas fases por
las que debe pasar la instrucción al ser procesada. Cada etapa puede procesar una instrucción
distinta en la fase correspondiente, por lo que el procesador puede aprovechar el paralelismo
entre instrucciones (ILP, Instruction Level Parallelism) al procesar simultáneamente varias
instrucciones (cada una en una fase distinta). La distribución de etapas que tenga un
procesador segmentado es una característica importante de su microarquitectura y afecta de
forma decisiva a sus prestaciones. Una posible distribución de etapas sería la que incluye una
etapa para captar la instrucción (IF, iniciales del inglés Instruction Fetch) desde la memoria
(usualmente desde la cache de instrucciones); otra para decodificar la instrucción captada y,
en su caso, acceder a los operandos que se utilizarán en la operación codificada por la
instrucción (ID/OF, de Instruction Fetch / Operand Decode); otra para la ejecución de la
operación (EX, de Execute); otra para esperar que la memoria proporcione el dato necesario
en una instrucción de carga o para escribir el dato en una instrucción de almacenamiento
(MEM); y finalmente una etapa para almacenar los resultados en de las operaciones en los
registros del procesador (WB, de Write Back). En un procesador segmentado se pueden
presentar problemas a causa de las dependencias entre las instrucciones procesadas en el
cauce. Si estas dependencias ocasionan una reducción en el rendimiento del cauce al impedir
que termine una instrucción cada ciclo (una vez transcurrido el tiempo de latencia de inicio),
ocasionan un riesgo. Existen riesgos de datos, por ejemplo cuando una instrucción necesita datos
de otra instrucción y éstos no se han generado todavía; riesgos de control, debidos a las
interrupciones o a las instrucciones de salto, que afectan al flujo de instrucciones que hay que
ejecutar; y riesgos estructurales o colisiones, debidos a recursos compartidos (por ejemplo buses
de acceso a memoria) por etapas diferentes. El efecto de los riesgos se puede paliar mediante
técnicas hardware y/o técnicas software.
INSTRUCCIÓN 1 2 3 4 5 6 7 8 9
add r3, r3, r1 IF ID EX WB
sub r5, r5, r3 IF Stall ID EX WB
add r4, r4, r1 IF ID EX WB
sub r6, r6, r4 IF Stall ID EX WB
INSTRUCCIÓN 1 2 3 4 5 6 7 8 9
add r3, r3, r1 IF ID EX WB
nop IF ID EX WB
sub r5, r5, r3 IF ID EX WB
add r4, r4, r1 IF ID EX WB
nop IF ID EX WB
sub r6, r6, r4 IF ID EX WB
INSTRUCCIÓN 1 2 3 4 5 6 7 8 9
add r3, r3, r1 IF ID EX WB
add r4, r4, r1 IF ID EX WB
sub r5, r5, r3 IF ID EX WB
sub r6, r6, r4 IF ID EX WB
En la Figura 1 se considera un cauce con cuatro etapas. En la primera etapa se captan las
instrucciones, en la segunda se decodifican y se accede a los operandos almacenados en el
banco de registros del procesador, en la siguiente etapa se ejecutan las operaciones
codificadas en la instrucción, y en la última etapa se almacenan los resultados en el banco de
registros. En la Figura 1.a se muestra el efecto de un riesgo de datos entre las instrucciones
primera y segunda y de otro riesgo entre la instrucción tercera y la cuarta. Como se puede
ver, hay que retrasar la captación de los operandos en la segunda y cuarta instrucciones hasta
que se haya completado la ejecución de las instrucciones primera y tercera, respectivamente.
Se producen atascos (stalls) en el cauce que hacen que no se pueda terminar el procesamiento
de una instrucción por ciclo. En la figura se ha supuesto que la escritura de los datos en el
banco de registros (en la última etapa) se produce al comienzo de la etapa (en el flanco de
subida de reloj) y la lectura de los datos (en la segunda etapa) se producen al final de la etapa
(en el flanco de bajada del reloj), y por eso sólo se debe esperar un ciclo en el atasco. La
Figura 1.b muestra una posible forma de evitar los riesgos introduciendo instrucciones de
no-operar para retrasar la segunda y la cuarta instrucción de la Figura 1.a con respecto a la
primera y tercera, respectivamente. En este caso se evita la necesidad de que exista algún
procedimiento hardware que gestione los atascos pero no se mejora la eficiencia del cauce.
En la Figura 1.c se pone de manifiesto cómo la reorganización de código puede evitar los
riesgos de datos y mejorar la eficiencia ya que en este caso, los retrasos entre instrucciones se
consiguen introduciendo instrucciones que tienen utilidad en el código. Este ejemplo pone
de manifiesto la importancia del trabajo del compilador en el rendimiento de los
procesadores segmentados. Por otra parte, también es posible solucionar este tipo de riesgos
mediante una solución hardware, incluyendo caminos de bypass o atajos que adelanten el
resultado de las unidades de ejecución a la siguiente instrucción.
INSTRUCCIÓN 1 2 3 4 5 6 7 8 9 10 11 12
add r4, r5, r2 IF ID EX WB
addi r5, r5, #1 IF ID EX WB
sub r3, r3, r1 IF ID EX WB
bnez r3, inicio IF ID EX WB
addi r2, r2, #1 IF ID EX WB
lw r6, 0(r2) IF ID EX WB
add r6, r3, r1 IF ID EX WB
INSTRUCCIÓN 1 2 3 4 5 6 7 8 9 10 11 12
add r4, r5, r2 IF ID EX WB
addi r5, r5, #1 IF ID EX WB
sub r3, r3, r1 IF ID EX WB
bnez r3, inicio IF ID EX WB
nop IF ID EX WB
nop IF ID EX WB
addi r2, r2, #1 IF ID EX WB
lw r6, 0(r2) IF ID EX WB
add r6, r3, r1 IF ID EX WB
INSTRUCCIÓN 1 2 3 4 5 6 7 8 9 10 11 12
sub r3, r3, r1 IF ID EX WB
bnez r3, inicio IF ID EX WB
add r4, r5, r2 IF ID EX WB
addi r5, r5, #1 IF ID EX WB
addi r2, r2, #1 IF ID EX WB
lw r6, 0(r2) IF ID EX WB
add r6, r3, r1 IF ID EX WB
# 2 3 4 5 6 … 245 246 247 248 249 250 … 474 475 476 477 478 479 480 481
(2) IF ID EX MEM WB
(3) IF ID EX MEM
(4) IF ID EX
(5) IF ID
(6) IF
…
(3) IF ID EX MEM WB
(4) IF ID EX MEM WB
(5) IF ID EX MEM
(6) IF ID EX
(7) IF ID
…
(5) IF ID EX MEM WB
(6) IF ID EX MEM WB
(7) IF ID EX MEM WB
(8) IF ID EX MEM WB
El efecto de las interrupciones y las excepciones en el cauce es muy pernicioso dado que dan
lugar a una bifurcación en la secuencia de instrucciones a procesar. Además, en el caso de las
interrupciones no catastróficas (aquellas que no causan que el programa concluya) se debe
regresar a la secuencia que se estaba procesando antes de la interrupción/excepción. La
dificultad que plantea el procesamiento de las interrupciones en un procesador segmentado
se deriva de que hay varias instrucciones procesándose simultáneamente y hay que identificar
qué instrucción es la que ha dado lugar a una excepción y qué instrucciones hay que ejecutar
antes de ceder el control a la rutina de gestión de la excepción (y por tanto qué instrucciones
hay que ejecutar al retomar el control de la secuencia que se ha interrumpido). Existen dos
alternativas para el procesamiento de interrupciones/excepciones en un procesador
segmentado: las interrupciones/excepciones precisas y las imprecisas. En el caso de las
precisas todo ocurre como si se tratase de un procesador no segmentado:
2. Una función puede tener que reutilizar alguna de las etapas por las que ya ha
pasado.
3. Las etapas pueden ser utilizadas en orden diferente por distintas funciones
(es el caso de los cauces multifuncionales).
ETAPA 1 2 3 4 5 6 7 8 9
S1 X X
S2 X X X
S3 X
S4 X X
S5 X X
Dada la tabla de reservas se determina la lista de latencias prohibidas, es decir los intervalos
de tiempo entre los que las etapas del cauce se vuelven a reutilizar. Para ello se van
considerando las etapas una a una y se incluyen en la lista de latencias todos los intervalos de
tiempo entre todas las parejas de casillas marcadas en cada etapa. Por ejemplo, la etapa S2
introduce tres latencias prohibidas en la lista (1, 5, y 6), correspondiendo a los intervalos de
separación para cada una de las tres parejas de casillas marcadas que existen. El conjunto de
latencias prohibidas para esta tabla de reservas es F = {1, 5, 6, 8}. A partir de la lista de
latencias prohibidas se construye el vector de colisiones constituido por un número de
componentes igual al máximo número incluido en la lista de latencias prohibidas y cuyos
componentes se numeran empezando en uno desde la derecha. Un componente es igual a 1
si su índice está incluido en la lista de latencias prohibidas y es 0 en caso contrario. En el
ejemplo que consideramos, el vector de colisiones es C = (10110001). El vector de colisiones
representa los intervalos de tiempo en los que, tras introducir una función en el cauce vacío,
no se pueden introducir nuevas funciones debido a que causarían colisiones en el cauce.
A partir del vector de colisiones se puede construir un diagrama de estados cuyos nodos
indican las latencias prohibidas del cauce en para una determinada combinación de funciones
introducidas en el mismo y cuyos arcos se marcan con los intervalos de tiempo que hay que
esperar para pasar del estado de partida del arco al estado al que apunta al introducir una
nueva función en el cauce. En la Figura 4 se muestra el procedimiento para determinar los
estados siguientes a uno dado. Los arcos que salen del estado de partida están marcados con
el número de intervalos de tiempo que se espera para introducir la nueva función. Como se
ve, todos corresponden a ceros en el estado de partida (no son latencias prohibidas). El
estado de partida se desplaza un número de componentes hacia la derecha, igual al número
de ciclos que han transcurrido y se introduce ese número de ceros por la izquierda. Después
se debe hacer la unión bit a bit con el vector de colisiones, para contabilizar las latencias
prohibidas que introduce la nueva función que se ha introducido en el cauce. Con todas las
posibles formas de salir de cada uno de los estados se construye un diagrama como el que se
muestra en la Figura 5 para la tabla de reservas de la Tabla 1.
En ese diagrama, los estados de cada ciclo indican qué latencias están prohibidas en función
de las operaciones que haya actualmente en el cauce, y las etiquetas de los arcos el número ce
ciclos que tienen que transcurrir para aceptar una nueva operación. Con ayuda de este tipo de
diagramas se pueden determinar ciclos de latencias válidas para acepar operaciones, y con
estos ciclos, se podrá construir el planificador que gestione el cauce de forma óptima. Un
ciclo no es más que un camino cíclico que pasa por uno o varios estados del diagrama y que
comienza y termina en el mismo estado. La latencia total del ciclo será la suma de las
latencias de cada uno de los arcos que lo componen, y su latencia media, LM, será el cociente
su latencia total y el número de arcos que lo compongan. Si la unidad de control del cauce
funciona de forma que se introducen instrucciones según un ciclo determinado, la
productividad máxima (expresada en funciones u operaciones por ciclo) que puede conseguir
es el cociente entre el número de instrucciones y el tiempo correspondiente a la latencia total
del ciclo, o lo que es lo mismo W = 1 / LM. Por lo tanto, nos interesa identificar el ciclo de
mínima latencia media, (MLM), ya que la unidad de control diseñada según este ciclo nos
proporcionará la productividad máxima para el cauce, Wmax = 1 / MLM.
7, 9+
10110001
7, 9+
7, 9+ 3 2 7, 9+ 7, 9+
10110001 10110001
3
4 2
10110001 10110001
En la Figura 5 se han resaltado dos de los ciclos posibles. El ciclo de la izquierda tiene una
latencia media LM = (7 + 2 + 2) / 3 = 3.67, mientras que para el ciclo de la derecha,
LM = (3 + 4) / 2 = 3.5. Por lo tanto, una unidad de control diseñada según el ciclo de la
derecha es mejor que si se diseña a partir del ciclo de la izquierda.
Los dos ciclos que se han resaltado reciben el nombre de ciclos avariciosos porque se
construyen saliendo de cada estado por el arco que implica esperar el menor tiempo para
introducir una nueva función en el cauce. Identificar el mejor de los ciclos avariciosos y
realizar el diseño de la unidad de control según el mismo es una estrategia aproximada para
obtener la mejor unidad de control que puede ser útil en el caso de diagramas de flujo
complicados (con muchos ciclos de funcionamiento posibles).
Solución
El tiempo de ejecución de n operaciones en el circuito original se calcula como:
Torig n n T 450n ns
Conocidos los tiempos de ejecución en los circuitos original y segmentado, se puede calcula la
ganancia en velocidad que se obtiene usando el circuito segmentado con la siguiente expresión:
Torig n 450n 3n
S n
Tseg n 150n 450 n 3
n n n 109
W n operaciones/ns operaciones/s
Tseg n 150n 450 150n 450
3n
S max lim S n lim 3
n n3
n
n 109
Wmax lim W n lim 6.6 106 operaciones/s
n n 150n 450
Por último, el valor de n para el que se alcanza un 90% de la productividad se calcula despejando n a
partir de la igualdad:
n 109
W n 0.9 W max 6.6 106 operaciones/s
150n 450
b) ¿Cómo se podrían reorganizar las instrucciones para que los riesgos de tipo
RAW no tuvieran ningún efecto? (Considere que intervienen los caminos de
bypass).
Solución
La Figura 6 muestra una traza de la ejecución del fragmento de código del enunciado. En el diagrama
se observa que se pierden 4 ciclos en los que no termina ninguna instrucción debido a la dependencia
de tipo RAW que existe entre las instrucciones (4) y (5) respecto al registro r4, debido a que el
resultado de la multiplicación (4) es el operando de la instrucción (5), y la multiplicación tarda cinco
ciclos en completarse. Por ello, aunque haya varias unidades funcionales, que podrían aprovecharse en
paralelo en este caso (hay un multiplicador y un sumador en el cauce), la suma debe esperar a que
termine la multiplicación.
INSTRUCCIÓN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
lw r1, 0x1ac IF ID EX MEM OS
lw r2, 0x1fc IF ID EX MEM OS
add r3, r0, r0 IF ID EX MEM OS
mult r4, r2, r1 IF ID EX MEM OS
add r3, r3, r4 IF ID Stall EX MEM OS
add r5, r0, 0x1ac IF Stall ID EX MEM OS
add r6, r0, 0x1fc Stall IF ID EX MEM OS
sub r5, r5, #4 IF ID EX MEM OS
sub r6, r6, #4 IF ID EX MEM OS
sw (r5), r3 IF ID EX MEM OS
sw (r6), r4 IF ID EX MEM OS
Teniendo en cuenta que en este cauce las instrucciones terminan de forma ordenada, las dependencias
de datos que pueden afectar son las de tipo RAW. Las WAW y WAR no dan problemas porque al
escribirse los resultados en el banco de registros sólo en la última etapa, se puede estar seguro que en
el momento en que escribe una instrucción, todas las instrucciones anteriores han realizado sus
escrituras, y por supuesto, sus lecturas.
Para contabilizar las dependencias de tipo RAW se toman aquellas instrucciones que estén separadas
por menos (estrictamente) de dos instrucciones, ya que son las que podrían estar simultáneamente en
el cauce, y en donde la instrucción que entra en primer lugar en el cauce puede escribir sus resultados
después de que las que le siguen vayan a leerlos (no se respetaría que la lectura ha de ser posterior a la
escritura). Aquí se está considerando que la escritura en el banco de registros en la etapa OS se realiza
al comienzo del ciclo, y que la lectura en dicho banco se hace al final del ciclo, ya que si no fuera así,
las instrucciones separadas por otras dos instrucciones sí que podrían ocasionar pérdidas de ciclo en
los riesgos RAW. Teniendo esto en cuenta, las dependencias de tipo RAW que existen son:
El RAW (2)-(4) ocasiona 1 ciclo perdido. Este ciclo perdido retrasa la captación de
(5) respecto a (3) y el RAW (3)-(5) no ocasiona pérdidas de ciclos.
Igual pasa con el RAW (8)-(10), éste ocasiona la pérdida de 1 ciclo, pero al retrasar
la captación de (11), hace que desaparezca el efecto del RAW (9)-(11).
En cuanto al segundo apartado del problema, pueden existir distintas formas de reorganizar el código
para que los riesgos de tipo RAW no tengan efecto. El objetivo es separar las instrucciones entre las
que existían riesgos de tipo RAW que producían pérdidas de ciclos utilizando otras instrucciones,
evitando que se introduzcan nuevos riesgos problemáticos, y lógicamente, sin cambiar el resultado del
programa.
En el caso que nos ocupa, se perdían 4 ciclos por el riesgo de tipo RAW existente entre las
instrucciones (4) de multiplicación (que duraba 5 ciclos) y la (5) de suma. Para resolver el problema,
una posibilidad es retrasar la instrucción (5), introduciendo entre ella y la instrucción (4) las
instrucciones (6), (7), (8), y (9) ya que no dependen de la (5). De esta forma, la instrucción (10) pasaría
a estar a continuación de la (5) habría un riesgo de tipo RAW (por r3). Si se utilizan caminos de bypass
no se perderían ciclos, pero, en cualquier caso, es posible reordenar (10) y (11) para que haya más
separación entre (5) y (10). De esta forma, el código quedaría:
Al ejecutarlo, se puede observar que se necesitan 16 ciclos. Es decir, uno más que el valor mínimo,
dado que aparece un riesgo estructural. En concreto, en el ciclo 11 intentan acceder a la etapa de
memoria las instrucciones (4) y (9), y dado que sólo puede hacer una instrucción en cada etapa
simultáneamente, la instrucción (9) y siguientes deben esperar un ciclo. Esta situación se puede
comprobar en la Figura 7.
INSTRUCCIÓN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
lw r1, 0x1ac IF ID EX MEM OS
lw r2, 0x1fc IF ID EX MEM OS
add r3, r0, r0 IF ID EX MEM OS
mult r4, r2, r1 IF ID EX MEM OS
add r5, r0, 0x1ac IF ID EX MEM OS
add r6, r0, 0x1fc IF ID EX MEM OS
sub r5, r5, #4 IF ID EX MEM OS
sub r6, r6, #4 IF ID EX Stall MEM OS
add r3, r3, r4 IF ID Stall EX MEM OS
sw (r6), r4 IF Stall ID EX MEM OS
sw (r5), r3 Stall IF ID EX MEM OS
Si se realizara la simulación suponiendo que no existen caminos de bypass se podría observar que el
tiempo de ejecución subiría a 20 ciclos. Se podría reducir un ciclo (similares prestaciones que en la
situación inicial del problema anterior, con el código sin reordenar y sin caminos de bypass) si se realiza
la simulación con el fragmento de código reordenado como se indica a continuación:
a) Suponiendo un cauce con las etapas IF, ID, EX, MEM, WB, en el que la
multiplicación tarda 5 ciclos y la suma de números en coma flotante tarda 2,
y hay un multiplicador y un sumador que pueden trabajar en paralelo, estime
el número de ciclos que se necesitarían, y aplique alguna técnica que permita
reducir los atascos (stalls) para este programa.
Solución
Un programa posible para realizar aX + Y es el que se muestra a continuación
donde rx y ry son las direcciones de memoria a partir de las que se encuentran almacenados los
componentes de los vectores. En el programa se ha fijado el número de componentes N = 64, por lo
que el número de bytes que componen el vector X (y lo mismo el vector Y) es igual a 64 × 8 = 512
bytes. De esta forma, r8 apunta al comienzo del vector X tras la instrucción (2); r4 apunta al final del
vector X (primer byte no ocupado por las componentes del vector) tras la instrucción (3); y r12 apunta
al comienzo de Y tras la instrucción (4). En cada iteración se va incrementando el valor de r8 y r12 en
8, ya que en cada iteración se hacen las operaciones correspondientes a un componente, y cada
componente tiene 64 bits (8 bytes). Para comprobar el final de las iteraciones se comparan r8 y r4.
INSTRUCCIÓN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
ld f0, a IF ID EX MEM WB
add r8, r0, rx IF ID EX MEM WB
addi r4, r8, #512 IF ID EX MEM WB
add r12, r0, ry IF ID EX MEM WB
ld f2, 0(r8) IF ID EX MEM WB
multd f2, f0, f2 IF ID Stall EX MEM WB
ld f4, 0(r12) IF Stall ID EX MEM WB
addd f4, f2, f4 Stall IF ID Stall EX MEM WB
sd 0(r12), f4 IF Stall ID Stall EX MEM WB
addi r8, r8, #8 Stall IF Stall ID EX MEM WB
addi r12, r12, #8 Stall IF ID EX MEM WB
sub r20, r4, r8 IF ID EX MEM WB
bnez r20, loop IF Stall ID
nop Stall IF ID Abort
ld f2, 0(r8) IF ID EX MEM
multd f2, f0, f2 IF ID Stall
ld f4, 0(r12) IF Stall
RAW entre la instrucción (6) y (8), ya que no puede empezar la suma de (8) hasta
que no se haya terminado la multiplicación de (6)
RAW entre (8) y (9), ya que hasta que no haya terminado la suma de (8) no podría
empezar la ejecución de (9).
RAW entre las instrucciones (12) y (13), ya que se supone que, como en el caso del
procesador DLX, en la fase de decodificación de la instrucción de salto (13) se debe
haber ejecutado la instrucción anterior (12).
Como se puede comprobar en la en la Figura 8, aún adelantando el procesamiento del salto a la etapa
de decodificación, se introduce una instrucción incorrectamente en el cauce (la instrucción 14), que se
debe anular una vez que se ejecuta el salto. También se puede observar que en el ciclo 10 se están
ejecutando dos instrucciones simultáneamente, (6) y (7). Esto es posible porque, como dice el
enunciado, además de la ALU, el procesador dispone de un multiplicador que puede operar en
paralelo. Por otra parte, la figura también muestra que la instrucción (7) puede terminar antes que la
(6), dado que no existen dependencias entre ellas y no afecta al resultado.
El tiempo de ejecución de una iteración es de 16 ciclos (desde que se capta la instrucción (5) hasta que
se vuelve a captar, tras la instrucción de salto). Así, si se realizan N iteraciones, el tiempo consumido
por el programa sería 16 × N, pero a este número hay que sumar, los 4 ciclos correspondientes a las
instrucciones que están fuera del bucle (al principio), más los tres ciclos que hay que esperar para que
termine la última instrucción del programa (14). Por lo tanto, este programa tardaría:
T N 4 16N 3 16N 7
Una forma de mejorar las prestaciones del programa es desenrollar el bucle. En el código que se
muestra a continuación, se ha aplicado esta técnica de forma directa. Es decir, se duplican las
instrucciones de una iteración del bucle sin desenrollar, excepto la instrucción de resta utilizada para
determinar el final de las iteraciones.
En el código anterior los números de instrucciones (5’),..., (11’) designan a las instrucciones
correspondientes a (5),...., (11) en una iteración del bucle.
Para determinar el tiempo tardaría en ejecutarse el programa en este caso, se puede utilizar el diagrama
de etapas y tiempos utilizado anteriormente. En este caso, el tiempo transcurrido entre que se capta la
instrucción (5) y se capta la instrucción (12) es igual a 12 ciclos (17 - 5 = 12). Como una iteración tiene
dos secuencias similares de instrucciones (5) - (11) y (5´) - (11’), se tendrán que contabilizar 2 × 12
ciclos = 24 ciclos para la secuencia (5),…, (11), (5’),…, (11’). Además, habrá que añadir cuatro ciclos
correspondientes al ciclo de captación de la instrucción de resta (para el control del final del bucle), y a
los tres ciclos asociados a la instrucción de salto. En el esquema de etapas y ciclos presentado, estos
cuatro ciclos son los 17, 18, 19 y 20.
Así pues, cada iteración necesita 28 ciclos (en lugar de los 16 del bucle sin desenrollar), pero hay que
ejecutar la mitad de iteraciones (N / 2). Por lo tanto, si a eso se unen los cuatro ciclos de las
instrucciones iniciales, y los tres que hay que esperar para que termine la ejecución de la última
instrucción, el tiempo necesario (suponiendo N par) es:
N
Tdesenrollado N 4 28 3 14 N 7
2
De esta forma, se reduce el tiempo de ejecución en 2N ciclos con respecto al bucle inicial. Se puede
reducir algo más el tiempo de ejecución si se reordenan las instrucciones en el código correspondiente
al bucle desenrollado (aprovechando que en cada iteración se tienen más instrucciones para
reordenar). Una posible forma de reordenar las instrucciones se muestra a continuación.
Los cambios realizados con respecto al primer bucle desenrollado buscan distanciar en el código
aquellas instrucciones entre las que existían riesgos ocasionaban pérdidas de ciclos. Así, para evitar el
riesgo RAW entre las instrucciones (5) y (6), se ha introducido entre ellas la instrucción (7). Entre las
instrucciones (6) y (8) se han introducido dos instrucciones sin dependencias entre ellas ni con (6) u
(8) por lo que se reduce en uno, el número de ciclos que se pierden en la situación anterior, ya que
entre (6) y (8) hay dos instrucciones en lugar de una. Igualmente, entre (6’) y (8’) se han introducido
tres instrucciones, y se reducen en dos, el número de ciclos que se perdían por las dependencias entre
la multiplicación y la suma. Sin embargo, al quedar las instrucciones (9’) y (11’), una al lado de otra, se
produce una pérdida de un ciclo por la dependencia en r12.
Así pues, en cada iteración se pierden cuatro ciclos debido a dependencias, con respecto al caso ideal
en el que cada instrucción tarda un ciclo. Así pues, como en la iteración hay 14 instrucciones y se
pierden 4 ciclos, el tiempo de cada iteración es 14 + 4 = 18, más un ciclo que se pierde siempre
después de la instrucción de salto. En total tenemos que cada iteración necesita 19 ciclos, y por tanto
(teniendo en cuenta que N es par):
N
Tdesenrollado2 N 4 19 3 9.5N 7
2
De esta forma, se ganan 4.5 ciclos por iteración con respecto al desenrollado anterior, y 6.5 ciclos por
iteración con respecto a la situación inicial.
En cuanto al segundo apartado del problema, el siguiente código muestra una forma posible de aplicar
segmentación software al programa original.
En el programa, las instrucciones (1) – (4) coinciden con las del programa inicial, y permiten que r8
apunte al comienzo del vector X, r12 al comienzo del vector Y, r4 al primer byte después del vector
X, y f0 se carga con el dato a.
Después, el grupo de instrucciones (5) – (10), que van desde la posición loop0 hasta la loop se hacen las
cargas de la primera iteración, los cálculos de la primera iteración y las cargas de la segunda iteración,
dejando los registros preparados para que comience el cuerpo del bucle segmentado. La instrucción
(5) carga f2 con la primera componente de X, y se multiplica por a en la instrucción (6). La instrucción
(7) carga la primera componente de Y en f4, y las instrucciones (8) y (9) cargan las segundas
componentes de X e Y en f6 y f8, respectivamente. La instrucción (10) realiza la suma de la primera
componente de aX y la primera de Y. Como se puede ver, se han introducido las instrucciones (8), y
(9) entre esta instrucción y la instrucción (7) donde se carga la primera componente de Y, para retrasar
la ejecución de (10) con respecto a (6) y a (7), y reducir el efecto de los riesgos RAW.
En la primera iteración, las instrucciones (12) y (15) realizan los cálculos con los
datos correspondientes a la segunda componente, a los que se ha accedido mediante
las instrucciones (8) y (9). Por lo tanto, en la iteración i del bucle, se realizan las
operaciones con las componentes i + 1.
En la última iteración, (11) almacena la última componente del resultado; (12) y (15)
hacen un cálculo innecesario con datos que se captaron en la iteración anterior por
(16) y (17); y (16) y (17) captan datos innecesarios. Dado que el efecto de (12) y (15)
en la última iteración, y los de (16) y (17) en la última y en la penúltima no afectan al
resultado del programa, no hace falta deshacer su efecto o evitar que se ejecuten.
En el bucle, se han reordenado las instrucciones para evitar el efecto de los riesgos
RAW. Así, (12) y (15) están lo más separadas posible, y lo mismo pasa con (13) y
(16), y con (14) y (17).
El tiempo de ejecución del programa en este caso se puede estimar si se tienen en cuenta las
instrucciones entre las que hay dependencias de tipo RAW y su separación. Así:
Entre la instrucción (5) y (6) hay un RAW que dará lugar a un ciclo perdido por que
cuando empieza la multiplicación todavía no se ha terminado el acceso a memoria: 1
ciclo perdido
Entre la (6) y la (10) también hay un RAW, y puesto que la multiplicación que se
realiza en la (6) tarda (5) ciclos, se perderá un ciclo, ya que se introducen 3
instrucciones entre la (6) y la (10): 1 ciclo perdido
Entre la (1) y la (11) hay un RAW, y puesto que la suma tarda dos ciclos, se perderá
un ciclo (suponiendo que hay adelantamiento, o caminos de bypass para llevar el
resultado de la suma directamente al registro para el almacenamiento en memoria):
1 ciclo perdido
Entre la (12) y la (15) hay un RAW, igual que entre la (5) y la (6). No obstante,
como ahora sólo se introducen dos instrucciones entre ellas, se perderán dos ciclos:
2 ciclos perdidos
Al terminar (15) se pierde un ciclo, debido ya que la suma tarda dos ciclos y habrá
un riesgo estructural con alguna de las instrucciones que la siguen para acceder a la
etapa MEM: 1 ciclo perdido.
Entre la (18) y la (19) se pierde otro ciclo debido al riesgo RAW que existe entre
estas instrucciones, y a que se necesita haber ejecutado (terminado la etapa EX) la
instrucción (18) antes de que (19) esté en su etapa de decodificación (ID): 1 ciclo
perdido.
Teniendo en cuenta el efecto de los riesgos en los ciclos perdidos tenemos que el tiempo del programa
anterior se puede calcular como sigue:
4. Tiempo de las instrucciones (1) - (10) y primera iteración del bucle (11) - (19):
19 (número de instrucciones) +
7 (ciclos perdidos) –
3 (la primera instrucción de la segunda iteración empieza justo después de la
etapa ID de la instrucción de salto (19)) = 27 ciclos
9 (número de instrucciones) +
4 (ciclos perdidos por las dependencias entre instrucciones dentro del bucle) –
Sumando 1), 2), y 3) se tiene un total del 912 ciclos, que supone una reducción de 1031 - 912 = 119
ciclos (11.5% de reducción) con respecto a la situación inicial del problema.
Es decir, que la reducción de tiempo sería aproximadamente igual a 2N, con respecto a la situación
inicial (para valores de N suficientemente grandes). Como se ve, se tiene una complejidad similar a la
que se obtenía con el desenrollado.
En cualquier caso, es posible obtener mejores prestaciones todavía si se reorganizan algo más las
instrucciones para evitar la pérdida de algunos ciclos por los riesgos existentes. Por ejemplo, en el
programa que se muestra a continuación:
Después de la reordenación realizada, sólo se pierden dos ciclos por iteración: uno debido a
dependencia RAW entre (12) y (15), entre las que se han introducido 3 instrucciones, y otro ciclo
debido a un riesgo estructural al terminar (15) puesto que las instrucciones que la siguen sólo necesitan
un ciclo en la etapa EX.
Solución
Una forma posible de aprovechar que las instrucciones que siguen a una instrucción de salto se
ejecuten normalmente es poner la primera instrucción de una iteración (la instrucción (5)) después de
la instrucción de salto. Por supuesto, en el caso de que no se produzca el salto también se ejecutará, y
habrá que estudiar si esto tiene efectos en la semántica del programa.
Otra posible mejora consiste en poner una instrucción de la iteración que siempre tiene que ejecutarse,
pero no afecta a la condición del salto. En el programa anterior se podría situar detrás de la
instrucción de salto, una de las instrucciones que actualizan los registros que sirven de puntero para ir
accediendo a los componentes del vector: instrucción (11). En ese caso, el código sería:
En cualquier caso, hay que asegurarse que, al cambiar de sitio una instrucción, no se empeora el efecto
de posibles dependencias que no afectaban porque la instrucción retardaba la captación de una
instrucción con respecto a otras. En el código anterior, la instrucción (11) retardaba la ejecución de
(12) respecto de (10). No obstante, si se considera que hay caminos de bypass, esta dependencia de
tipos RAW entre (10) y (12) no tiene efecto.
Solución
Para el caso en que el procesador no anule nunca la instrucción situada a continuación del salto, el
código del programa sería el siguiente:
Como el código utiliza la ALU para hacer todas las operaciones aritméticas, la latencia de todas las
operaciones es de un ciclo, con lo que suponiendo que existen caminos de bypass, no existirían atascos
en el cauce. Para aprovechar el salto retardado se ha retrasado la instrucción que incrementa r1, que se
ejecutará tanto si se salta como si no.
Para el caso de que el procesador anule la instrucción a continuación del salto si no se salta (se supone
que siempre se va a saltar), el código anterior funcionaría sin problemas, ya que sólo se anularía el
incremento de r1 en la última iteración, cuando ya no hace falta volver a usarlo. Por último, si el
procesador anulara siempre la instrucción que está situada a continuación del salto, habría que subir el
incremento de r1 antes del salto y colocar tras el salto una instrucción nop, para que su anulación no
nos cause ningún problema.
Solución
El programa se ejecuta correctamente, ya que en cada iteración se ejecutará la instrucción de
almacenamiento que hay detrás del salto y el efecto que tendrá será simplemente el de almacenar la
suma parcial acumulada en f0. Sin embargo, esta operación, aunque no provoca que el resultado sea
incorrecto, sí que repercute en el tiempo de ejecución del programa, ya que si el vector X tiene N
elementos, se realizarán N – 1 almacenamientos que consumen un tiempo de ejecución que podría
usarse para algo más provechoso. Por ejemplo, una posible optimización podría ser la siguiente:
En este caso, la instrucción de después del salto retardado se utiliza para incrementar el puntero al
siguiente elemento de X, instrucción que hay que realizar de todas formas, con lo que el cuerpo del
bucle pasa a tener una instrucción menos que antes. Además, la instrucción de resta se ha colocado
detrás la instrucción de carga para ocultar su retardo carga-uso.
Para obtener la productividad del cauce primero tenemos que calcular cuánto tiempo tarda en
ejecutarse el programa para un vector de N elementos. Para ello es necesario realizar una traza de su
ejecución, tal y como muestra la Figura 9. En esta traza podemos observar que se producen dos
atascos en el cauce, el primero de ellos en el ciclo 6 debido a un riesgo estructural entre las
instrucciones (2) y (3) en la etapa MEM, y el segundo debido a un riesgo RAW entre las instrucciones
(5) y (6). También podemos observar que se tarda dos ciclos en comenzar la primera iteración del
bucle, que desde que se capta la primera instrucción del bucle transcurren 9 ciclos hasta que se
resuelve el salto, por lo que podemos concluir que cada iteración del bucle tarda 9 ciclos, y que tras la
última iteración es necesario terminar de ejecutar las dos últimas instrucciones, lo que tarda otros
cinco ciclos. Por tanto, el tiempo de ejecución del programa es de:
T N 2 9N 5 9N 7
INSTRUCCIÓN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
add r1, r0, r0 IF ID EX MEM WB
subd f0, f0, f0 IF ID EX EX MEM WB
ld f2, X(r1) IF ID EX Stall MEM WB
subi r3, r3, #8 IF ID Stall EX MEM WB
multd f6, f2, f4 IF Stall ID EX EX EX MEM WB
addd f0, f0, f6 Stall IF ID Stall EX EX MEM WB
bnez r3, bucle IF Stall ID
addi r1, r1, #8 Stall IF ID EX MEM WB
sd R, f0 IF ID EX MEM WB
Nº instrucciones 6N 3
WN instr./ciclo
Tiempo 9N 8
Nº resultados N
WN resultados/ciclo
Tiempo 9N 8
7. Suponga que en el siguiente programa N = 108, a y c son dos vectores de números en coma
flotante, y b es un escalar en coma flotante.
Solución
Una posible codificación del bucle anterior podría ser:
La Tabla 2 muestran las modificaciones que serían necesarias para optimizar el programa en cada caso.
Cualquiera de las soluciones de los casos 2 y 4 son intercambiables para ambos casos.
8. Una función F se va a implementar en un cauce con 5 etapas S1, S2, S3, S4, S5 de forma que
visita las etapas según la secuencia: S1 S5 S1 S4 S3 S2 S1 S4. Obtenga la ganancia en
velocidad con respecto a la ejecución sin cauce para 200 operaciones, teniendo en cuenta que
sin cauce la función requiere un tiempo de 16 ns y que las etapas del cauce suponen unos
tiempos de ejecución de 4 ns para S1, S4 y S5, 5 ns para S2, y 3 ns para S3 (incluyendo los
retardos de los registros de acoplo). ¿Cuál es la productividad en función del número de
operaciones? Determine los valores de la productividad máxima y la ganancia máxima.
Solución
Con ayuda de la Tabla 3, que muestra la tabla de reservas del cauce, podemos obtener sus latencias
prohibidas F = {2, 4, 6}, y su vector de colisiones C = (101010), a partir del cual se puede dibujar su
diagrama de estados, mostrado en la Figura 10. Con ayuda de este diagrama se calcula su mínima
latencia mínima como:
53
MLM 4 ciclos
2
ETAPA 1 2 3 4 5 6 7 8
S1 X X X
S2 X
S3 X
S4 X X
S5 X
7+
7+
101010
7+
3
7+ 5 1
5
101111 101011 111111
3 5
Teniendo en cuenta que el tiempo de los registros de acoplo está incluido en el de las etapas, fijaremos
el tiempo de reloj del cauce a:
t maxt 1 , t 2 , t 3 , t 4 , t 5 d max3,4,5 5 ns
Una vez obtenidos MLM y t, podemos calcular el tiempo que tardarían en procesarse n operaciones en
el cauce segmentado como:
Torig n n T 16n ns
Torig n 16n 4n
S n
Tseg n 20n 1 5n 1
4 200
S 200 0.799
5200 1
La productividad en función del número de operaciones se define como:
n n n 109
W n operaciones/ns operaciones/s
Tseg n 20n 1 20n 1
Por último, la ganancia y la productividad máximas del cauce se obtienen aplicando el límite cuando
n → ∞ a la ganancia y a la productividad respectivamente:
4n 4
S max lim S n lim
n 5n 1 5
n
n 109
Wmax lim W n lim 50 106 operaciones/s
n n 20n 1
9. Se han encontrado dos posibles alternativas para la ejecución de una función F en un cauce
con 4 etapas S1, S2, S3, S4. La alternativa 1 visita las etapas según la secuencia
S1 S3 S1 S3 S2 S4 S4, y la alternativa 2 en el orden S1 S2 S3 S2 S3 S4 S2.
Solución
El primer paso para responder al primer apartado es calcular la tabla de reservas para cada una de las
dos alternativas (Tabla 4 y Tabla 5). A partir de estas tablas se pueden obtener las latencias prohibidas
y los vectores de colisiones de los dos cauces:
ETAPA 1 2 3 4 5 6 7
S1 X X
S2 X
S3 X X
S4 X X
Tabla 4. Tabla de reservas para la primera alternativa del cauce del problema 9.
ETAPA 1 2 3 4 5 6 7
S1 X
S2 X X X
S3 X X
S4 X
Tabla 5. Tabla de reservas para la segunda alternativa del cauce del problema 9.
Para determinar qué alternativa tiene la máxima productividad, realizamos un diagrama de estados
para cada cauce a partir de su vector de colisiones (Figura 11 y Figura 12). Con ayuda de estos
diagramas podemos encontrar los ciclos de latencia mínima de cada cauce:
MLM1 3
1 6
MLM2 3.5
2
11
Figura 11. Diagrama de estados para la primera alternativa del cauce del problema 9.
10110
1 4
6 6
11111 10111
Figura 12. Diagrama de estados para la primera alternativa del cauce del problema 9.
Una vez calculadas las MLM de los dos cauces, sus tiempos de ejecución se calculan mediante:
sus productividades:
n n
W1 n operaciones/s
Tseg1 n 7 n 1 3 t
n n
W2 n operaciones/s
Tseg2 n 7 n 1 3.5 t
n 1 1
Wmax1 lim W1 n lim operaciones/s
n n k1 n 1 MLM1 t MLM1 t 3 t
n 1 1
Wmax2 lim W2 n lim operaciones/s
n n k n 1 MLM t MLM t 3.5 t
2 2 2
De estas expresiones se puede concluir que la productividad de la primera alternativa es mayor que la
de la segunda.
Para responder a la segunda cuestión, primero debemos calcular el tiempo de ejecución secuencial
para n operaciones:
Torig n n 15 15n ns
Una vez calculados estos dos tiempos, la ganancia en velocidad de cada alternativa se define como:
Torig n 15n 15n
S1 n
Tseg1 n 7 n 1 3 4.1
12.3n 16.4
Torig n 15n 15n
S 2 n
Tseg 2 n 7 n 1 3.5 4.1 14.35n 1
Así que para obtener la ganancia obtenida al procesar 1000 operaciones, sólo hay que sustituir
n = 1000 en las ecuaciones anteriores:
Torig 1000
S 1 1000 1.22
Tseg1 1000
Torig 1000
S 2 1000 1.04
Tseg 2 1000
10. La Tabla 6 muestra la tabla de reservas de un cauce que puede ejecutar dos funciones, A y B.
Determine las latencias prohibidas y construya el diagrama de estados para dicho cauce.
ETAPA 1 2 3 4 5
S1 A B A B
S2 A B A
S3 B A, B
Solución
Los conjuntos de latencias prohibidas y los vectores de colisiones cruzadas para las secuencias de
instrucciones AA, BA, AB, y BB son los siguientes:
FBA = {1, 2}: Representan las latencias prohibidas que aparecen al introducir una
instrucción A, para las instrucciones de tipo B que se quieran introducir después.
FAB = {1, 2, 4}: Representan las latencias prohibidas que aparecen al introducir una
instrucción B, para las instrucciones de tipo A que se quieran introducir después.
FBB = {2, 3}: Representan las latencias prohibidas que aparecen al introducir una
instrucción B, para las instrucciones de tipo B que se quieran introducir después.
Puesto que el valor mayor de latencia prohibida incluida en los conjuntos anteriores es 4, los vectores
de colisiones tendrán 4 componentes y serán:
C AA 0100
M A
C BA 0011
C AA 1011
M B
C BA 0110
La Figura 13 muestra el diagrama de estados obtenido a partir de ellas. En dicho diagrama, desde
cualquier estado se pasa al estado inicial indicado por MA (MB) cuando se introduce una instrucción A
(B) en el cauce tras esperar 5 o más ciclos. Ese es el significado de la flecha que llega a MA (MB)
marcada con A5+ (B5+).
B3, B4
A5+ B5+
A4 A3 B1
A4
A2 B3, B4 B4
0100 0101 1011 1111
0011 0011 0110 0111
A2
A4 B3, B4
B4
0110
0011
A1 A1
0111 B3, B4
0011
A4
11. Las cuatro etapas de un cauce multifuncional, S1, S2, S3 y S4, se utilizan por las
instrucciones del tipo A de la forma S1 S2 S1 S3 S1 S4 S1 y por las instrucciones del tipo B
de la forma S1 S4 S1 S3 S1 S2 S1. Escriba las matrices de colisiones cruzadas y determine
cuál es la productividad máxima del cauce para una secuencia de instrucciones del tipo A (es
decir A, A, A,…) teniendo en cuenta que la frecuencia de reloj es de 500 MHz.
Solución
El primer paso para calcular las matrices de colisiones cruzadas es obtener la tabla de reservas,
mostrada en la Tabla 7. Con esta tabla es fácil obtener las latencias prohibidas:
C AA 101010
M A
C BA 101010
C AA 101010
M B
C BA 101010
ETAPA 1 2 3 4 5 6 7
S1 A, B A, B A, B A, B
S2 A B
S3 A, B
S4 B A
Para calcular la productividad máxima para una secuencia del tipo A, sólo debemos tener en cuenta el
vector de colisiones CAA = (101010), que nos genera el diagrama de estados que muestra la:
1 5
101010
5
3 5
7
111111 101111 101011
1 7
MLM 4 ciclos
2
Con lo que para una secuencia de n operaciones la productividad del cauce es de:
y la productividad máxima:
5n
Wmax lim W ( n ) lim 108 125 106 operaciones/s
n n 4n 3
ETAPA 1 2 3 4
S1 A, C B, C
S2 A, B, C A A
S3 B C
Solución
A partir de la tabla de reservas del enunciado se pueden obtener las latencias prohibidas del cauce:
11 10 10
M A 11, M B 00 , M C 10
11 10 10
Siguiendo una planificación avariciosa del cauce, se pasarían por los estados que muestra la Figura 15,
por lo que el tiempo total de ejecución de la secuencia sería de 16 ciclos, como si indica en el diagrama
de tiempos de la Figura 16.
11 11
A3
11 01
11 11
C3
B1
B3
10 10 11
C1
10 00 10
10 10 11
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
A
B
C
B
A
C
ETAPA 1 2 3 4
S1 A, C B
S2 A, B, C B A
S3 B A, C
Solución
Las latencias prohibidas del cauce son:
10 11 00
M A 11, M B 01, M C 10
10 11 00
A partir de estas matrices se puede dibujar el diagrama de estados que muestra la Figura 17 y la traza
que muestra la Figura 18, que indica que a secuencia de operaciones tarda 12 ciclos en ejecutarse.
10 00
A1
11 10
B3 10 00
B2
C1 C2
11 01
01 11
11 01
1 2 3 4 5 6 7 8 9 10 11 12
A
C
C
A
B
B
14. Se tiene un cauce multifuncional con 4 etapas, S1, S2, S3, S4, que puede ejecutar dos tipos de
operaciones, X, e Y. Las operaciones del tipo X recorren el cauce según la secuencia
S2 S4 S3 S1 S1 S2, mientras que las de tipo Y lo hacen en el orden S1 S2 S1 S2 S3 S4. Si el
bucle interno de un programa realiza intensivamente la secuencia de operaciones
X Y Y X X Y Y Y, ¿cuánto tiempo tardaría en ejecutarse el cuerpo del bucle si la frecuencia
de reloj es de 1 GHz?, ¿Cuál es la productividad máxima del cauce para esa secuencia?
Solución
A partir de la tabla re reservas del cauce (Tabla 10) podemos determinar las matrices de colisiones del
cauce:
1 0 0 0 1 0 1 1 1 1
M X , M Y
0 1 1 1 1 0 0 0 1 0
Como en el enunciado nos piden que calculemos cuánto tiempo tarda en ejecutarse la secuencia de
operaciones X Y Y X X Y Y Y, no tenemos que dibujar el diagrama de estados completo, sino sólo la
parte que se utiliza para determinar las latencias de esta secuencia, tal y como muestra la Figura 19.
ETAPA 1 2 3 4 5 6
S1 Y Y X X
S2 X Y Y X
S3 X Y
S4 X Y
X (1)
X5 (4)
10001 01111
01111 X5 (1 - Sig. Iter.) 00011
Y3 (8)
X2 (5)
Y5 (2)
Y1 (3,7)
10101 01111
01111 00010
Y5 (6)
Una vez dibujado el diagrama de estados, ya conocemos el instante en el que se inicia la ejecución de
cada operación en el cauce, por lo que podemos dibujar la traza de la ejecución, mostrada en la Figura
20. Con ayuda de esta gráfica podemos concluir que la secuencia de operaciones tarda 28 ciclos, que
con un reloj de 1 GHz son 28 ns.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
X
Y
Y
X
X
Y
Y
Y
Siguiente iteración del bucle X
Para calcular la productividad máxima para esta secuencia tenemos que tener en cuenta que la
siguiente iteración no puede comenzar hasta el ciclo 28, ya que tenemos que esperar 5 ciclos después
de la última Y para introducir la X de la siguiente secuencia, como indica el diagrama de estados, así
que podremos empezar una nueva secuencia cada 27 ciclos, por tanto, el tiempo para calcular n
secuencias será:
TLI n 1 MLM 28 n 1 27
T n 27n 1 ns
F 109
Y la productividad máxima:
n n 109
Wmax lim W n lim lim 37.04 106 iteraciones/s
n n T n n 28 n 1 27
15. Un procesador segmentado tiene 5 etapas S1, S2, S3, S4, S5 y todas tardan un ciclo excepto
la etapa S3 (etapa de ejecución) que, según las instrucciones puede tardar 2 o 3 ciclos. ¿Cuál
es la velocidad pico de ese procesador si funciona a 500 MHz? ¿Qué mejora podría
implementar para mejorar esa velocidad pico? ¿Qué valor alcanzaría entonces?
Solución
Teniendo en cuenta que una etapa dura dos ciclos para un tipo de instrucciones y tres ciclos para otro
tipo, en el mejor de los casos, si todas las instrucciones del programa son de aquellas en las que la
etapa S3 duran dos ciclos, se puede terminar una instrucción cada dos ciclos. Por tanto, la velocidad
pico se puede estima a partir de:
F 500 106
R pico 250 106 instrucciones/s
CPI 2
Este apartado se podría resolver de forma más rigurosa a partir de la tabla de reservas del cauce (Tabla
11), de la que se pueden obtener sus latencias prohibidas:
Una vez determinadas sus latencias prohibidas, se puede obtener su diagrama de estados (Figura 21),
en el que se puede comprobar fácilmente que cualquier ciclo que se construya tiene una latencia media
que estará entre 2 (como mínimo) y 3 (como máximo).
ETAPA 1 2 3 4 5 6 7
S1 A, B
S2 A, B
S3 A, B A, B B
S4 A B
S5 A B
A2+ B2 B3+
01 11
01 11
A3
La velocidad pico se corresponderá con la situación en que la MLM (mínima latencia media) sea igual
a 2. Con esta MLM la productividad máxima del cauce será de:
Para mejorar la velocidad del procesador, una posible mejora consiste en añadir otras dos etapas S3
que puedan funcionar simultáneamente, tal y como muestra la Figura 22. Además de añadir estas dos
etapas S3 adicionales, habría que mantener las instrucciones de tipo A en la etapa S3 durante tres
ciclos en lugar de dos ciclos.
S3
S1 S2 S3 S4 S5
S3
Figura 22. Primera alternativa para la optimización del cauce del problema 15.
Otra posibilidad consiste en rediseñar la etapa S3 de forma que conste de tres etapas independientes
de un ciclo cada una de ella, tal y como muestra la Figura 23. En este caso, también debe ocurrir que
las instrucciones de tipo A pasen por las tres etapas nuevas.
Figura 23. Segunda alternativa para la optimización del cauce del problema 15.
Con cualquiera de estas modificaciones, el tiempo de latencia inicial de cualquier instrucción sería de 7
ciclos, y cada ciclo terminaría de ejecutarse una instrucción. De esta forma, la velocidad pico sería:
F 500 106
R pico 500 106 instrucciones/s
CPI 1
16. La Tabla 12 muestra la tabla de reservas de un sumador segmentado con cuatro etapas S1,
S2, S3, S4. Indique cuál es la productividad máxima de este cauce si se utiliza un reloj con
una frecuencia de 2 GHz. ¿A partir de qué número de sumas segmentadas consecutivas se
alcanza el 90% de la productividad máxima? ¿Qué cambios haría en la etapa S3 para mejorar
el rendimiento del cauce?
ETAPA 1 2 3 4 5
S1 X X
S2 X
S3 X X
S4 X
Solución
El conjunto de latencias prohibidas del cauce es F = {1, 4}, por lo tanto, su vector de colisiones es
C = (1001). La Figura 24 muestra el diagrama de estados del cauce, del que se puede obtener su
MLM = 2.5.
n nF n 2 109 8n
W n 108 operaciones/s
T n TLI n 1 MLM 5 n 1 2.5 n 1
3,
1001
5+
3, 5+ 2
1011
Para determinar el valor de n con el que se alcanza el 90% de la productividad máxima se despeja n de
la igualdad:
0.9 Wmax 0.9 8 108 8n
n 1
108
obteniéndose n = 9.
Para mejorar las prestaciones del cauce, se podría segmentar la etapa S3 en dos nuevas etapas de la
mitad de duración, tal y como muestra la Tabla 13. Así, en lugar de 4 se tendrían 5 etapas y la única
latencia prohibida sería F = {4}. Si se hace el diagrama de estados partiendo de C = (1000) se observa
que la mínima latencia media que se obtiene en este caso es menor que 2.5.
ETAPA 1 2 3 4 5
S1 X X
S2 X
S31 X
S32 X
S4 X
Tabla 13. Tabla de reservas para cauce optimizado del problema 16.