Académique Documents
Professionnel Documents
Culture Documents
El tiempo de eje
u
ión de un programa sabemos que depende del número de instru
iones,
del número de
i
los por instru
ión y de la dura
ión del
i
lo, según la siguiente expresión:
Tejecución = N I × CP I × Ciclo
Para una determinada arquite
tura y una apli
a
ión, tanto el número de instru
iones
omo la
dura
ión del
i
lo son jos,
on lo que el úni
o fa
tor sobre el que se puede in
idir para redu
ir
su tiempo de eje
u
ión es el número de
i
los por instru
ión. Sin embargo, el número de
i
los
por instru
ión está dire
tamente inuen
iado por el número de
i
los de deten
ión que tiene
esa apli
a
ión en esa arquite
tura. Como sabemos, este número de
i
los por instru
ión
depende del CPI base del pro
esador y del número de
i
los de deten
ión en media por
instru
ión. Éstos, a su vez, son las deten
iones (SCPI) que provo
a el
au
e del pro
esador
y las que provo
a la jerarquía de memoria.
19
20 CAPÍTULO 1. PARALELISMO A NIVEL DE INSTRUCCIÓN
Este solape poten
ial entre las instru
iones se llama paralelismo a nivel de instru
ión
(ILP), ya que las instru
iones pueden eje
utarse en paralelo. Sin embargo, el ILP se ve di-
re
tamente limitado por las dependen
ias entre instru
iones. Buena parte de estos
i
los de
deten
ión son debidos a riesgos de datos por distintos tipos de dependen
ias entre las instru
-
iones. Así pues, para in
rementar las presta
iones va a ser fundamental eliminar el máximo
posible de dependen
ias para obtener el máximo número de instru
iones independientes.
Así pues, sin tener en
uenta la jerarquía de memoria, el número de
i
los por instru
ión
en un pro
esador segmentado es la suma del CPI base y las deten
iones por instru
ión que
provo
an los distintos tipos de riesgos:
El CPI ideal es una medida de las presta
iones máximas al
anzables por una implementa
ión
dada. Mediante la redu
ión de las deten
iones que introdu
en los distintos tipos de riesgos, se
puede minimizar el número de
i
los por instru
ión total, y por tanto in
rementar el número
de instru
iones por
i
los (IPC). En este
apítulo se verá que las té
ni
as que se pueden
usar para in
rementar el IPC ideal pueden aumentar la importan
ia de solu
ionar
uando sea
posible los riesgos estru
turales, de datos y de
ontrol.
Casi todas las té
ni
as que se van a estudiar a lo largo de los siguientes
apítulos explotan
el paralelismo existente entre las instru
iones. Normalmente, la
antidad de paralelismo en
un bloque bási
o (una se
uen
ia de instru
iones
onse
utivas sin saltos) es bastante pequeña.
Para los programas SPEC la fre
uen
ia media de saltos está entre un 15 % y un 25 %, lo que
signi
a que en media sólo entre
uatro y siete instru
iones se pueden eje
utar antes de que
o
urra un salto. Además, hay que tener en
uenta que entre estas instru
iones es probable que
también o
urran dependen
ias de datos. Por tanto, el solape entre instru
iones que se puede
explotar es bastante pequeño. Así pues, para obtener mejoras importantes de presta
iones, se
debe explotar el ILP disponible a través de múltiples bloques bási
os.
Para redu
ir los riesgos existentes entre las instru
iones y por tanto aumentar el ILP
disponible en las apli
a
iones se suelen utilizar té
ni
as de análisis en tiempo de
ompila
ión
y de análisis en tiempo de eje
u
ión. Así por ejemplo, para redu
ir los riesgos estru
turales se
pueden repli
ar o segmentar las unidades fun
ionales, y para redu
ir las deten
iones por riesgos
de
ontrol se puede utilizar la té
ni
a de saltos retardados. Hay que señalar que ambas té
ni
as
son estáti
as puesto que no dependen de de
isiones que se tomen en tiempo de eje
u
ión. En la
tabla 1.1 pueden observase diversas té
ni
as que pueden apli
arse para mejorar las presta
iones
de un pro
esador segmentado, y qué
ara
terísti
a redu
e
ada una de ellas.
El número de
i
los por instru
ión que
onsigue una determinada apli
a
ión en una arqui-
te
tura dada tiene una estre
ha rela
ión
on la
antidad de paralelismo a nivel de instru
ión
disponible en esa apli
a
ión. De he
ho, el paralelismo a nivel de instru
ión nos indi
a la
posibilidad de solapamiento en las se
uen
ias de instru
iones, y depende del grado de depen-
den
ia entre las instru
iones. Hay que señalar que dos instru
iones son independientes si se
pueden eje
utar simultáneamente sin que existan
oni
tos entre ellas. Así,
uando se tiene
un alto paralelismo entre las instru
iones es que hay po
as dependen
ias y por tanto po
os
oni
tos entre ellas,
on lo que se produ
irán po
as deten
iones durante la eje
u
ión y
omo
1.2. TIPOS DE DEPENDENCIAS 21
Té
ni
a Redu
e
Desenrollamiento de bu
les Riesgos de
ontrol
Plani
a
ión dinámi
a
on mar
ador Riesgos RAW
Plani
a
ión dinámi
a
on renombramiento Riesgos WAR y WAW
Predi
ión dinámi
a de saltos Riesgos de
ontrol
Emisión múltiple de instru
iones CPI ideal
Análisis de dependen
ias del
ompilador CPI ideal y riesgos de datos
Segmenta
ión software CPI ideal y riesgos de datos
Plani
a
ión de trazas CPI ideal y riesgos de datos
Espe
ula
ión Riesgos de datos y de
ontrol
Elimina
ión dinámi
a de ambigüedad en memoria Riesgos RAW
on memoria
Cuadro 1.1: Diversas té
ni
as que pueden apli
arse para mejorar las presta
iones y qué
a-
ra
terísti
a redu
e
ada una de ellas.
onse
uen
ia el número de
i
los por instru
ión
onseguido estará bastante próximo al base
de la arquite
tura utilizada.
Hay tres tipos diferentes de dependen
ias: dependen
ias de datos (también llamadas de-
penden
ias verdaderas), dependen
ias de nombre y dependen
ias de
ontrol. Vamos a ver de
forma detallada
ada uno de estos tipos de dependen
ias.
o si hay dependen
ia de datos entre la instru
ión I y otra instru
ión K , y la instru
ión
K produ
e un resultado que usa la instru
ión J
La segunda
ondi
ión indi
a una
adena de dependen
ias del primer tipo entre varias
instru
iones. Evidentemente, esta
adena de instru
iones puede prolongarse durante mu
has
instru
iones a lo largo de todo el programa.
22 CAPÍTULO 1. PARALELISMO A NIVEL DE INSTRUCCIÓN
Ejemplo 1.1 Considerar la siguiente se
uen
ia de
ódigo que in
rementa los valores de un
ve
tor en memoria (
omenzando en la posi
ión 0(R1)) sumándole un es
alar alma
enado
en F2:
Las dependen
ias de datos en esta se
uen
ia de
ódigo involu
ran tanto a los datos de
punto otante (PF)
omo a los enteros. En
uanto a los datos de punto otante hay
una dependen
ia de datos en rela
ión a F0 entre el resultado que produ
e la
arga y
su utiliza
ión en la suma, y otra dependen
ia en rela
ión a F4 entre el dato produ
ido
por la suma y su utiliza
ión en el alma
enamiento. En
uanto a los datos enteros, la
dependen
ia es en rela
ión a R1 entre el dato produ
ido por la resta de enteros y la
instru
ión de salto.
Si dos instru
iones tienen dependen
ias de datos eso signi
a que no se pueden eje
utar
simultáneamente, o por lo menos de forma
ompletamente solapada. La dependen
ia nos di
e
que hay una posible
adena de uno o más riesgos de datos entre instru
iones. Si se intentan
eje
utar esas instru
iones al mismo tiempo en un pro
esador que in
orpora dete
ión de
riesgos, eso va a provo
ar deten
iones en la segunda de las instru
iones para evitar el riesgo,
on lo que se redu
e el solape entre las instru
iones, y por tanto también las presta
iones
al
anzadas por el pro
esador.
Si por
ontra las instru
iones se van a eje
utar en un pro
esador que no in
orpora de-
te
ión de riesgos, esa tarea re
ae en el
ompilador, que debe ha
er una plani
a
ión de
instru
iones tal que no se eje
uten las instru
iones dependientes de forma solapada, pues la
eje
u
ión del programa no sería
orre
ta. La plani
a
ión del
ompilador tratará de reordenar
el orden de eje
u
ión de las instru
iones sin afe
tar al resultado nal, y
uando ni aún así se
onsigan resolver las dependen
ias habrá que in
luir instru
iones NOP para separar entre sí
las instru
iones dependientes y de esa manera evitar que surja el riesgo de datos.
Hay que señalar que las dependen
ias de datos son propias de los programas, pero si
esas dependen
ias terminan
onvirtiéndose en riesgos de datos depende de la organiza
ión
del
au
e que tenga el pro
esador. Así, podemos en
ontrar dependen
ias de datos que
ausen
riesgos en unos pro
esadores mientras que en otros no. Así pues, si unas dependen
ias de
datos terminan provo
ando deten
iones y degradando las presta
iones ideales dependerá de
la organiza
ión
on
reta del
au
e del pro
esador donde se va a eje
utar esa se
uen
ia de
instru
iones. Esta diferen
ia entre dependen
ias y riesgos es fundamental para entender
ómo
se puede explotar el paralelismo a nivel de instru
ión.
En nuestro ejemplo, hay una dependen
ia de datos entre las instru
iones SUBI y BNEZ,
que
ausa una deten
ión si el salto se resuelve en la etapa ID, pero que no
ausaría ninguna
deten
ión si el salto se resuelve en la etapa MEM, pues en ese
aso la
ondi
ión del salto se
evaluaría en la etapa EX y podría apli
arse adelantamiento, tal y
omo puede verse en la
1.2. TIPOS DE DEPENDENCIAS 23
gura 1.1. En di
ha gura se ha mar
ado el adelantamiento que se produ
iría en
uanto está
listo el resultado de SUBI a la etapa que debe utilizarlo.
(a) (b)
Figura 1.1: Situa
ión entre las instru
iones SUBI y BNEZ del ejemplo, (a)
uando el salto
se resuelve en ID, y (b)
uando el salto se resuelve en la etapa MEM.
La presen
ia de una dependen
ia indi
a un riesgo poten
ial, pero si realmente hay un
riesgo, y el número de
i
los de deten
ión que eso involu
ra, depende del
au
e del pro
esador.
La importan
ia de las dependen
ias de datos es que una dependen
ia de datos:
Puesto que una dependen
ia de datos puede limitar la
antidad de paralelismo a nivel
de instru
ión que se puede explotar, en varios
apítulos de esta asignatura se va a tratar
este tema intentando limitar los efe
tos de esas dependen
ias de datos. Estos efe
tos pueden
limitarse de dos formas distintas: manteniendo la dependen
ia pero evitando que pueda surgir
un riesgo, o eliminando la dependen
ia mediante la transforma
ión del
ódigo. En este sentido,
el primer método que se suele utilizar para evitar los riesgos de datos es plani
ar el
ódigo sin
eliminar las dependen
ias. Como se verá más adelante, algunos tipos de dependen
ias pueden
eliminarse por software y/o mediante té
ni
as hardware.
Un valor de un dato puede pasar entre instru
iones bien mediante registros, bien por la
memoria. Si para ello se utilizan los registros, es bastante sen
illo dete
tar la dependen
ia
pues los nombres de los registros son jos en las instru
iones. Sin embargo, los saltos pueden
ompli
ar esa dete
ión, pues dependiendo del resultado nal del salto, las dependen
ias
variarán. En estos
asos, tanto el
ompilador
omo el hardware suelen tomar una postura más
onservadora para no arriesgar y asegurar la
orre
ión del resultado nal.
Las dependen
ias que involu
ran posi
iones de memoria son más difí
iles de dete
tar,
puesto que dos dire
iones distintas pueden estar reriéndose realmente a la misma posi
ión
de memoria. Por ejemplo, las dire
iones 100(R4) y 20(R6) podrían referirse a la misma
posi
ión físi
a dependiendo de los valores de R4 y R6. Además, la dire
ión efe
tiva de una
arga o un alma
enamiento podría
ambiar entre distintas eje
u
iones de la misma instru
ión
(por ejemplo, en un bu
le),
ompli
ando aún más la dete
ión de posibles dependen
ias. En
su momento estudiaremos té
ni
as hardware para dete
tar las dependen
ias de datos que
involu
ran posi
iones de memoria, aunque in
luso esas té
ni
as tienen sus limita
iones.
24 CAPÍTULO 1. PARALELISMO A NIVEL DE INSTRUCCIÓN
Dadas dos instru
iones I y J (J situada después de I ), podemos tener dos tipos de
dependen
ias de nombre:
1. una antidependen
ia entre la instru
ión I y la instru
ión J o
urre si la instru
ión
J es
ribe sobre un registro o una posi
ión de memoria que lee la instru
ión I . El
orden original debe preservarse para asegurar que la instru
ión I lee el valor
orre
to.
Podemos observar este tipo de dependen
ia en la siguiente se
uen
ia de instru
iones:
I ≡ R1 ← R2 + R3
J ≡ R2 ← R5 + R6
2. una dependen
ia de salida o
urre
uando las dos instru
iones I y J es
riben sobre el
mismo registro o posi
ión de memoria. El orden original debe preservarse para asegurar
que el valor que al nal se es
ribe
orresponde a la instru
ión J . Podemos observar este
tipo de dependen
ia en la siguiente se
uen
ia de instru
iones:
I ≡ R1 ← R2 + R3
J ≡ R1 ← R4 + R5
En
ualquiera de los dos
asos, puede observarse que no hay una ne
esidad real de
omu-
ni
a
ión entre las dos instru
iones involu
radas en la dependen
ia, y se trata tan sólo de la
reutiliza
ión del mismo nombre para dos
osas distintas. Como una dependen
ia de nombres
no es una dependen
ia real, las instru
iones involu
radas en este tipo de referen
ias pueden
eje
utarse simultáneamente o reordenarse, siempre y
uando se
ambie el nombre (el regis-
tro o la posi
ión de memoria) usado en las instru
iones, para que no haya
oni
to. Este
renombramiento puede ha
erse más fá
ilmente si los operandos son registros, en
uyo
aso
se llama renombramiento de registros. Este renombramiento de registros puede ha
er-
se tanto estáti
amente por el
ompilador,
omo dire
tamente por el hardware en tiempo de
eje
u
ión.
Uno de los ejemplos más sen
illos de dependen
ia de
ontrol se da entre las instru
iones
de la parte then de una instru
ión if:
1.2. TIPOS DE DEPENDENCIAS 25
if p1 {
S1;
};
if p2 {
S2;
};
Las instru
iones del bloque S1 tienen una dependen
ia de
ontrol
on p1, y las instru
-
iones del bloque S2 tienen otra dependen
ia de
ontrol
on p2, pero no
on p1.
En general, hay dos normas que imponen las dependen ias de ontrol:
1. Una instru
ión que tiene una dependen
ia de
ontrol
on un determinado salto no
puede ser situada delante del salto de forma que su eje
u
ión ya no esté
ontrolada por
ese salto. Por ejemplo, no se puede tomar una instru
ión de la parte then y situarla
delante de la parte if.
2. Una instru
ión que no tiene una dependen
ia de
ontrol
on un determinado salto no
puede ser situada detrás de ese salto de forma que su eje
u
ión ahora esté
ontrolada
por el salto. Continuando
on el ejemplo, no se puede
ambiar una instru
ión desde
delante de la parte if a la parte then.
Al
ontrario de lo que podría pare
er, las dependen
ias de
ontrol no tienen por qué
suponer una pérdida de presta
iones si se puede realizar eje
u
ión espe
ulativa. Es de
ir,
si podemos eje
utar instru
iones que no deberían de haberse eje
utado, violando de esa
forma las dependen
ias de
ontrol, sin afe
tar a la
orre
ión del programa. En ese
aso
las dependen
ias de
ontrol no son un fa
tor
ríti
o que deba mantenerse. En su lugar, las
dos propiedades que sí deben mantenerse para asegurar la
orre
ión del programa son el
omportamiento de las ex
ep
iones y el ujo de los datos. Normalmente, esto se
onsigue
manteniendo tanto las dependen
ias de
ontrol
omo las de datos.
Consideremos dos instru
iones I y J de forma que según el
ódigo fuente la instru
ión
I se eje
uta antes que la instru
ión J , y por tanto también se pondrá la instru
ión I antes
que la instru
ión J en el
au
e de eje
u
ión. Los posibles riesgos por dependen
ia de datos
entre estas dos instru
iones son:
RAW (Read After Write, le
tura después de es
ritura): la instru
ión J trata de leer un
operando fuente antes de que lo es
riba la instru
ión I . De esta forma la instru
ión
J toma in
orre
tamente el valor antiguo, tal y
omo puede verse en la gura 1.2. Este
es el
aso más
omún de riesgo de datos, y viene provo
ado por una ne
esidad real de
omuni
a
ión, pues la segunda instru
ión ne
esita para su eje
u
ión el dato que está
al
ulando la primera.
I: ADD R1, R2, R3
WAR (Write After Read, es
ritura después de le
tura): en este
aso la instru
ión J intenta
es
ribir un destino antes que sea leído por la instru
ión I . Esta instru
ión toma in
o-
rre
tamente el nuevo valor, tal y
omo puede verse en la gura 1.3. Este tipo de riesgo
1.3. TIPOS DE RIESGOS 27
no puede darse en el DLX segmentado para enteros (aunque sí que se dará en el
aso de
opera
iones en punto otante) porque todas las le
turas se ha
en antes (en ID) y todas
las es
rituras después (en WB) (gura 1.5). Este riesgo o
urre
uando hay instru
iones
que es
riben en un
i
lo ini
ial sus resultados, e instru
iones que leen sus operandos
fuente en un
i
lo más tardío, y resulta que la le
tura se produ
e en el tiempo después
que la otra instru
ión posterior reali
e su es
ritura.
Este riesgo viene provo
ado por una antidependen
ia que se produ
e por una reutiliza-
ión, en este
aso de R1. Los
ompiladores suelen resolver las antidependen
ias mediante
el renombramiento de registros que utilizan las instru
iones. Así por ejemplo, en el
a-
so anterior el riesgo desapare
ería si la instru
ión ADD utilizara
omo registro destino
R32, y se
ambiara en todas las instru
iones siguientes a J que utili
en
omo operando
fuente R1 por ese nuevo R32. En este sentido, mu
hos pro
esadores tienen más registros
de los que son a
esibles por el usuario. Es bastante habitual que tengan 64 registros,
de los
uales 32 pueden ser usados por el usuario y los otros 32 los utiliza el
ompilador
o dire
tamente el hardware, para los renombramientos que sean ne
esarios para resolver
las antidependen
ias.
WAW (Write After Write, es
ritura después de es
ritura): ahora la instru
ión J intenta
es
ribir un operando antes que sea es
rito por la instru
ión I . Las es
rituras se están
realizando en un orden in
orre
to, dejando en el destino el valor es
rito por la instru
ión
I en lugar del es
rito por la instru
ión J , tal y
omo puede verse en la gura 1.4.
Claramente el
aso RAR (Read After Read, le
tura después de le
tura) no es un riesgo, ya
que evidentemente no modi
amos en ningún momento el valor de la fuente. Por otra parte,
28 CAPÍTULO 1. PARALELISMO A NIVEL DE INSTRUCCIÓN
IF ID EX MEM WB IF ID EX MEM WB
IF ID EX MEM WB IF ID EX MEM WB
Figura 1.5: En el pro
esador DLX segmentado todas las le
turas de registros fuente se realizan
en la etapa ID y las es
rituras de resultados en la etapa WB.
omo ya se ha
omentado, en la gura 1.5 puede observarse la situa
ión de las etapas en el
au
e DLX de enteros, y por qué no pueden plantearse riesgos WAR ni WAW.
En general, estos riesgos de datos, que hemos planteado en el a
eso a los registros, también
pueden su
eder en el
aso de a
eso a una posi
ión de memoria. En el pro
esador DLX, al
tener sólo un
anal de a
eso a memoria, los a
esos se ha
en en orden. Sin embargo, este
problema podría apare
er si tuviéramos dos o más
anales de a
eso a memoria.
Estos riesgos que hemos estudiado ha
en que en los programas haya menos paralelismo a
nivel de instru
ión, lo que a su vez a
arrea que haya más instru
iones dependientes en el
au
e de eje
u
ión del pro
esador. Para evitar estos riesgos, durante la eje
u
ión se provo
an
deten
iones, lo que ha
e que aumente el número de
i
los por instru
ión que el
au
e ne
esita
para eje
utar el programa.
ompilador ha generado las instru
iones. El análisis a nivel de bu
le realiza una dete
ión
de las dependen
ias existentes entre los operandos que intervienen entre las itera
iones de
ese bu
le. Como veremos, si no hay dependen
ias se puede desenrollar el bu
le, lo que nos
permitirá al
anzar mejores presta
iones. En lo que sigue sólo vamos a
onsiderar dependen
ias
de datos (se
al
ula un valor que se utiliza
omo operando fuente más adelante), pues aunque
también pueden su
eder dependen
ias de nombres, éstas pueden eliminarse mediante té
ni
as
de renombramiento.
El análisis del paralelismo a nivel de bu
le se
entra en estudiar si los a
esos a los datos
en las itera
iones su
esivas son dependientes de valores
al
ulados en itera
iones previas. Este
tipo de dependen
ia entre itera
iones se llama loop-
arried dependen
e.
En este bu
le hay una dependen
ia entre las dos ve
es que se usa x[i℄, pero esta
dependen
ia es en una misma itera
ión, no entre distintas itera
iones. De esta forma, el
bu
le puede ser fá
ilmente paralelizable. Como un ejemplo de este tipo de paraleliza
ión
el siguiente
ódigo presenta el mismo
ódigo anterior donde el bu
le se ha desenrollado
uatro ve
es:
Sin embargo, en mu
hos bu
les sí que tenemos dependen
ias entre itera
iones, lo que
ompli
ará o in
luso impedirá su desenrollamiento.
Puede observarse
omo este bu
le presenta dos dependen
ias entre itera
iones: en la
primera instru
ión hay una dependen
ia entre itera
iones relativa a la variable x[i℄ y
x[i+1℄, y en la segunda instru
ión la dependen
ia está en el uso de la variable y[i℄ e
y[i+1℄. Además, también hay una dependen
ia de datos entre la primera y la segunda
instru
ión respe
to al valor de x[i+1℄.
Al ser las itera
iones dependientes entre sí, el bu
le no se puede desenrollar, pues siempre
tendríamos deten
iones entre las instru
iones dependientes.
30 CAPÍTULO 1. PARALELISMO A NIVEL DE INSTRUCCIÓN
Supongamos que tenemos tres arrays A, B y C que son distintos, y supongamos también
el siguiente bu
le:
1. La instru
ión S2 usa el valor A[i+1℄,
al
ulado por la instru
ión S1 en la misma
itera
ión.
2. La instru
ión S1 usa un valor
al
ulado por la instru
ión S1 en una itera
ión anterior.
En la itera
ión i se
al
ula A[i+1℄ que es leído en la itera
ión i+1. Lo mismo o
urre
on la instru
ión S2 y B[i℄.
Estas dos dependen
ias son diferentes y tienen efe
tos diferentes. La dependen
ia de la
instru
ión S1 respe
to a una itera
ión anterior de la propia instru
ión S1, es una dependen
ia
entre itera
iones que obliga a eje
utar de forma se
uen
ial las diversas itera
iones de esta
instru
ión.
La dependen
ia de S2 respe
to a S1 es en una misma itera
ión, y no entre itera
iones. Así,
si ésta fuera la úni
a dependen
ia del bu
le, se podrían eje
utar múltiples itera
iones de este
bu
le en paralelo
on tan sólo mantener el orden relativo entre los pares de instru
iones
on
la dependen
ia.
Se pueden representar grá
amente las dependen
ias entre instru
iones, representando
las instru
iones mediante nodos y las dependen
ias mediante un ar
o entre la instru
ión
que produ
e el resultado y la instru
ión que lo utiliza. Cada ar
o se etiqueta
on la distan
ia
entre itera
iones que plantea la dependen
ia. Para el
ódigo que estamos analizando, este
grafo de dependen
ias sería el mostrado en la gura 1.6.
1 1
0
S1 S2
En la gura tenemos las dos instru
iones S1 y S2, las dos dependen
ias entre itera
iones
(a distan
ia uno) para
ada una de las instru
iones, y la dependen
ia de datos. Cuando
el grafo de dependen
ias tiene un
i
lo
on distan
ia de la dependen
ia mayor o
igual que uno enton
es el bu
le no es paralelizable.
Ejemplo 1.5 Consideremos este otro ejemplo, donde de nuevo los arrays A, B, C y D son
distintos.
1.4. AUMENTANDO EL PARALELISMO A NIVEL DE INSTRUCCIÓN 31
La instru
ión S1 usa el valor asignado en la itera
ión previa por la instru
ión S2,
de forma que hay una dependen
ia entre itera
iones entre S2 y S1. Sin embargo, puede
observarse que esa dependen
ia es entre distintas instru
iones y no de la misma instru
-
ión entre varias itera
iones. Esto puede verse
laramente en el grafo de dependen
ias
de la gura 1.7.
0
1
S1 S2
Figura 1.7: Grafo de dependen ias para el ódigo del ejemplo 1.5.
Estas dos observa
iones nos permiten sustituir el bu
le anterior por la siguiente se
uen
ia
de
ódigo:
Ahora la dependen
ia entre las dos instru
iones ya no es entre distintas itera
iones,
on
lo que pueden solaparse varias itera
iones del bu
le para eje
utarse de forma paralela,
siempre y
uando las instru
iones de
ada itera
ión mantengan su orden relativo.
32 CAPÍTULO 1. PARALELISMO A NIVEL DE INSTRUCCIÓN
La
omplejidad del análisis de dependen
ias está en el uso de arrays, punteros o paso de
parámetros por referen
ia, que permiten mu
hos lenguajes de alto nivel. Cuando sólo se usan
variables, el estudio de referen
ias es bastante sen
illo, pues sólo depende de los nombres de
las variables. Sin embargo,
uando se utilizan alias (
omo es el
aso de los punteros y del paso
de parámetros por referen
ia), surgen
ompli
a
iones e in
ertidumbre en el análisis.
El
ompilador puede usar varios métodos para en
ontrar las dependen
ias, y
on ello, si
es posible, eliminarlas. Algunos de esos métodos se basan en el he
ho de que los índi
es de
los arrays son anes. Un índi
e de un array de una dimensión es afín si se pueden es
ribir de
la forma a × i + b, donde a y b son
onstantes e i es la variable índi
e del bu
le. El índi
e de
un array de varias dimensiones es afín si lo son los índi
es de
ada dimensión. Los a
esos a
arrays dispersos, que típi
amente tienen la forma x[y[i℄℄, es uno de los prin
ipales ejemplos
de a
esos no anes.
Determinar si hay una dependen
ia entre dos referen
ias al mismo array en un bu
le es por
tanto equivalente a determinar si las dos fun
iones anes pueden tener el mismo valor para
diferentes índi
es dentro de los límites del bu
le. Por ejemplo, supongamos que tenemos en el
ódigo de un bu
le for, una instru
ión de alma
enamiento en un array y otra instru
ión que
lee de ese mismo array. Supongamos también que el índi
e de la instru
ión de alma
enamiento
puede expresarse en la forma a × i + b, y el índi
e de la instru
ión de le
tura del array puede
expresarse en la forma c × i + d, donde i es el índi
e del bu
le for que varía desde m hasta n.
En ese
aso existe una dependen
ia si se dan las siguientes
ondi
iones:
1. Existe dos índi
es de las itera
iones, j y k que están dentro de los límites del bu
le for,
es de
ir m ≤ j ≤ n, m ≤ k ≤ n.
2. La instru
ión de alma
enamiento guarda un resultado en una posi
ión que más adelante
utiliza la instru
ión de le
tura, es de
ir a × j + b = c × k + d.
Como un ejemplo, un test sen
illo y su
iente para
omprobar la ausen
ia de dependen
ias
es el máximo
omún divisor (GCD). Se basa en la observa
ión de que si hay una dependen
ia
entre itera
iones, enton
es se
umple que (d − b) mod GCD(c, a) = 0. Hay que señalar que
1.4. AUMENTANDO EL PARALELISMO A NIVEL DE INSTRUCCIÓN 33
para poder usar el test GCD se debe normalizar el bu
le, es de
ir, la variable índi
e del bu
le
debe empezar en uno e in
rementarse de uno en uno.
Ejemplo 1.6 Vamos a usar el test GCD para determinar si existen dependen
ias entre
itera
iones del siguiente bu
le:
Dado este
ódigo, los valores para las
onstantes de los índi
es son: a = 2, b = 3, c = 2
y d = 0. En este
aso el máximo
omún divisor de a y c es GCD(a, c) = 2. Mientras,
d − b = −3,
on lo que (d − b) mod GCD(c, a) = −3 mod 2 6= 0, y por tanto no hay
dependen
ia.
Hay que señalar que ésta es una
ondi
ión ne
esaria para garantizar dependen
ia pero no
es su
iente, pues puede que el test se
umpla y, sin embargo, que no haya dependen
ia entre
itera
iones. Esto puede su
eder, por ejemplo, si no se tienen en
uenta los límites del bu
le.
Por otra parte, el
ompilador, además de dete
tar si hay dependen
ias, debe dete
tar de
qué tipo son esas dependen
ias para tratar de eliminarlas
uando sea posible. De esta forma
se pueden re
ono
er las dependen
ias de nombres y eliminarlas en tiempo de
ompila
ión
mediante renombramiento.
Ejemplo 1.7 El siguiente bu
le tiene múltiples tipos de dependen
ias. Vamos a estudiar las
dependen
ias verdaderas, las de salida, las antidependen
ias, y eliminar las dependen
ias
de salida y antidependen
ias mediante renombramiento.
1. Hay dependen
ias verdaderas desde S1 a S3 y desde S1 a S4, debido a Y[i℄. Estas
dependen
ias no son entre distintas itera
iones,
on lo que no evitan que el bu
le
pueda paralelizarse. Sin embargo, estas dependen
ias obligan a que S3 y S4 deban
esperar a que termine S1.
2. Hay una antidependen
ia desde S1 a S2 debido a X[i℄.
3. Hay una antidependen
ia desde S3 a S4 debido a Y[i℄.
4. Hay una dependen
ia de salida desde S1 a S4 debido a Y[i℄.
1.5. Resumen
A lo largo de este
apítulo hemos visto la importan
ia que tiene aumentar el paralelismo a
nivel de instru
ión para
on ello mejorar las presta
iones que al
anza un sistema. Mejorando
el paralelismo a nivel de instru
ión se redu
en las dependen
ias y por tanto las deten
iones
que se provo
an durante la eje
u
ión en el
au
e segmentado,
on lo que disminuye el número
medio de
i
los por instru
ión.
Hemos revisado los distintos tipos de dependen
ias y
ómo se pueden evitar,
uando ésto
es posible. Se ha expli
ado que no todas las dependen
ias provo
an riesgos en la segmenta-
ión, pues eso depende de la distan
ia entre las instru
iones que tienen la dependen
ia y
la organiza
ión del
au
e donde se vaya a eje
utar el
ódigo. También se han revisado los
distintos tipos de riesgos que pueden o
urrir y su
orresponden
ia
on los distintos tipos de
dependen
ias entre instru
iones.
LD F0, 0(R1) ; S1
ADDD F4, F0, F2 ; S2
ADDD F6, F0, F4 ; S3
LD F2, 0(R3) ; S4
SUBI R3, R3, #4 ; S5