Está en la página 1de 70

Captulo 1 Introduccin a los Computadores Paralelos

1
Introduccin a los Computadores Paralelos
1. Qu es la computacin paralela?
Desde hace varias dcadas, el software siempre haba sido escrito para el
procesamiento en serie, siguiendo los paradigmas de la programacin estructurada.
El objetivo del cdigo era ser ejecutado en una computadora con una sola CP,
donde el problema era descompuesto en series discretas de instrucciones !ue se ejecutaban
una detr"s de otra, done slo una instruccin se poda ejecutar a la ve#, como se ilustra en la
siguiente figura$
Figura 1.1 Descomposicin de un problema en instrucciones serie
% diferencia de la anterior, en la programacin paralela el problema es dividido en
partes computacionales con el objetivo de ser ejecutadas en varias CP. Estas partes
discretas en el !ue el problema es descompuesto se van a resolver concurrentemente & cada
parte ser" dividida en una serie de instrucciones !ue se ejecutar"n simult"neamente en
diferentes unidades de procesamiento. De esta forma el tiempo de cmputo es mucho menor
al separar la complejidad de un problema en partes individuales !ue ser"n ejecutadas por
m'ltiples CP al mismo tiempo. Estas partes ser"n programas cu&as instrucciones se
ejecutar"n en una cauce paralelo diferente, como podemos apreciar en la siguiente figura$
( Carlos )imne# de Parga *
P R O B L ! "
Instruccin 1
Instruccin 1
Instruccin #
Instruccin #
Instruccin n $1
Instruccin n $1
Instruccin n
Instruccin n
%na sola CP%
%na sola CP%
Captulo 1 Introduccin a los Computadores Paralelos
Figura 1.# Ejecucin paralela
#. "plicaciones de la computacin paralela
+a computacin paralela es una evolucin de la computacin serie !ue intenta
emular los aspectos del mundo real & natural$ eventos complejos e interrelacionados
ocurriendo al mismo tiempo dentro de una secuencia. %s, tenemos la analoga de la
formacin de gala,ias, movimiento de planetas, patrones de eventos atmosfricos & de
ocanos, movimiento de las placas tectnicas, control de tr"fico, etc.
-istricamente la computacin paralela se ha considerado el punto final de la m"s
alta computacin & ha sido usada para resolver problemas complejos de ingeniera & ciencia
!ue acaecen en el mundo real.
.
P R O B L ! "
/nstruccin *
/nstruccin *
Instruccin #
Instruccin #
Instruccin n $1
Instruccin n $1
Instruccin n
Instruccin n
Instruccin 1
Instruccin 1
Instruccin #
Instruccin #
Instruccin n $1
Instruccin n $1
Instruccin n
Instruccin n
Instruccin 1
Instruccin 1
Instruccin #
Instruccin #
Instruccin n $1
Instruccin n $1
Instruccin n
Instruccin n
CP% 1
CP% 1
CP% #
CP% #
CP% &
CP% &
Captulo 1 Introduccin a los Computadores Paralelos
De esta forma encontramos el uso del paralelismo en computacin en los siguientes
entornos$
Cam'io clim(tico) 0e est"n utili#ando los patrones de cambios atmosfricos
para predecir con e,actitud los fenmenos alterados del tiempo.
*enoma) En el secuenciamiento de la estructura del %D1 del cdigo gentico.
+anotecnolog,a - .u,mica) Para crear nuevos compuestos moleculares con
propiedades microscpicas & materiales m"s resistentes a la fuer#a & al calor.
*eolog,a - sismolog,a) tili#ado en el estudio las propiedades geotcnicas & la
prediccin de movimientos ssmicos.
Ingeniar,a electrnica) Dise2o de circuitos con m"s nivel de integracin, m"s
r"pidos & con menos calentamiento del chip.
Prospeccin petrol,/era) Debido al agotamiento de los combustibles fsiles se
ha hecho patente la necesidad de b's!ueda de nuevos &acimientos para la
obtencin de petrleo & gas.
Buscadores 0e') Con la proliferacin incesante de /nternet en la 'ltima dcada
se necesita una gran cantidad de recursos de cmputo !ue para rastrear e inde,ar
todos los contenidos publicados en la red.

1iagnstico por imagen) El avance de la medicina re!uiere de sistemas de
imagen capaces de diagnosticar con precisin & sin errores la e,istencia de
enfermedades.
Industria /armacutica) En el dise2o de nuevos medicamentos eficaces con los
mnimos efectos secundarios.
!odelado econmico - /inanciero) +as transacciones financieras reali#adas en
un mundo globali#ado pueden poner en riesgo la economa mundial. El an"lisis
complejo de estas interacciones de agentes puede prevenir una posible crisis
econmica.
*r(/icos - realidad 2irtual) Con el fin de conseguir im"genes realistas en el
mundo de la infografa & los videojuegos.
( Carlos )imne# de Parga 3
Captulo 1 Introduccin a los Computadores Paralelos
&. "r.uitecturas 3on +eumann - secuenciales
El matem"tico h'ngaro )ohn 4on 1eumann sent las bases de la computacin
moderna a la !ue pertenecen los ordenadores secuenciales, tambin denominados
computadores serie. Este modelo se basa en la nidad Central de Procesamiento o CP
5acrnimo anglosajn de Central Processing Unit6, en la memoria donde se almacenan datos
e instrucciones. En esta ar!uitectura las instrucciones se ejecutan en serie !ue tratan con un
'nica secuencia de datos. En la seccin *.7 veremos m"s en profundidad los fundamentos
de este modelo.
Figura 1.& %r!uitectura 4on 1eumann 5CP & memoria6
Esta ar!uitectura presenta dos factores limitadores a tener en cuenta$ la velocidad a la
!ue se ejecutan las instrucciones & la velocidad de transferencia de datos e instrucciones
entre la memoria & la CP. En el primer factor est"n implicados los componentes & la
tecnologa electrnica 5frecuencia de reloj, etc.6. 1o obstante, desde los a2os noventa se han
desarrollado nuevas estrategias para aumentar el rendimiento. +a m"s conocida es la
segmentacin !ue consiste en ejecutar varias partes de un n'mero determinado de
instrucciones al mismo tiempo en varias unidades funcionales de c"lculo 5multiplicadores,
sumadores, unidades de carga & almacenamiento,...6. Esto se consigue dividiendo las partes
de ejecucin de una instruccin en etapas, alcan#ando un rendimiento bastante mejorado con
respecto a una m"!uina no segmentada o secuencial. En la figura *.7 podemos ver el
funcionamiento de una CP segmentada.
Instruccin Ciclo de relo4
1 # & 5 6 7 8 9 :
i /8 /D E9 :E: 0B
i+1 /8 /D E9 !! ;<
i+2 /8 /D ; :E: ;<
i+3 /8 I1 E9 :E: ;<
i+4 IF /D E9 :E: ;<
Figura 1.5 0egmentacin =/0C
7
! ! O R I "
! ! O R I "
%nidad de
Control
%nidad de
Control
"L%
Entrada
Entrada
0alida
0alida
Captulo 1 Introduccin a los Computadores Paralelos
Donde la etapa de ejecucin /8 es la b's!ueda de instruccin en la cach o en la
memoria principal, /D es la decodificacin de la instruccin & lectura de los registros, E9 es
la etapa ejecucin aritmtico lgica, :E: es la lectura & escritura en memoria, & finalmente
;< escribe el resultado en los registros.
Como el lector puede apreciar, la ventaja de esta estrategia radica en !ue es posible
adelantar la ejecucin de una instruccin en cada ciclo de reloj. En consecuencia en cada
ciclo de reloj se finali#a una instruccin & el incremento del rendimiento, sin tener en cuenta
los riesgos de la segmentacin, es de un factor de cinco con respecto a una m"!uina !ue
ejecuta las instrucciones en serie.
En contraposicin, aun!ue el incremento de la productividad es mu& alto con
segmentacin, el tiempo de CP !ue se le dedica a una instruccin individual es superior al
de su homlogo secuencial. Esto es debido a$
+os cerrojos !ue ha& !ue colocar en la circuitera para separar la informacin
entre etapas.
+a duracin de las etapas es similar & viene determinada por la etapa m"s larga.
+os riesgos estructurales, de datos & de control !ue introducen detenciones en el
cauce de ejecucin.
7*> ns 7*> ns. 7*> ns.
?> ?> @> ?> ?> ?> ?> @> ?> @> ?> ?> @> ?> ?>
/nstruccin * /nstruccin . /nstruccin 3
@Ans @Ans @Ans @Ans @Ans
/nstruccin * @> @> @> @> @>
/nstruccin . @> @> @> @> @>
/nstruccin 3 @> @> @> @> @>
Ans
Figura 1.6 4ersin no segmentada 5arriba6 & segmentada de tres instrucciones 5abajo6
( Carlos )imne# de Parga A
Captulo 1 Introduccin a los Computadores Paralelos
Como puede observarse en la figura *.A, la instruccin no segmentada consume 7*>
ns. , mientras !ue su e!uivalente segmentada consume 7BA ns. , a causa de la etapa m"s lenta
!ue es @> ns, en este caso suponiendo una segmentacin ideal & un retardo de A ns. Por los
cerrojos de cada etapa segmentada. Esto implica un aumento de productividad !ue no
siempre est" asociado a un incremento de velocidad de ejecucin.
Con respecto a la segundo problema de la segmentacin, ste admitira dos
soluciones.
%tili<ar memoria entela<ada o intercalada =memor- interlea2ing>)
Esta estrategia ar!uitectnica permite dividir la memoria en blo!ues, cada
uno con acceso independiente, tal & como puede verse en la siguiente figura$
Figura 1.7 :emoria entrela#ada
%tili<ar una memoria cac?)
Ctra estrategia m"s conocida para aumentar la velocidad de intercambio de
informacin es la memoria cach. Con esta memoria se consigue ma&or velocidad de
intercambio en un espacio de direcciones m"s pe!ue2o, en detrimento del coste de la
tecnologa. Con este tcnica se consigue el objetivo del principio de localidad, en la caben
dos posibles casos$ +a localidad espacial !ue consiste en el hecho de !ue la instruccin
siguiente a la !ue se est" ejecutando est" en la cercana del blo!ue en uso, +a localidad
temporal !ue consiste en !ue los datos o instrucciones !ue ser"n accedidos a continuacin
ser"n los !ue han sido accedidos recientemente.
En la siguiente figura *.B de la siguiente p"gina se muestra una ar!uitectura !ue
utili#a memoria cach$
D
CP%
CP%
!emoria 1
!emoria 1
!emoria #
!emoria #
!emoria n
!emoria n
Captulo 1 Introduccin a los Computadores Paralelos
Figura 1.8 %r!uitectura con memoria entrela#ada & memoria cach
+os procesadores segmentados son 'tiles para aplicaciones cientficas & de
ingeniera. n procesador segmentado, en trmino generales, siempre va a utili#ar una
memoria cach para evitar !ue las instrucciones de acceso a memoria sean mu& lentas.
1o obstante, en las aplicaciones cientficas, los datos de grandes dimensiones son
accedidos con baja localidad, & de esta manera el rendimiento !ue se consigue en la
jerar!ua de memoria es bastante pobre & con un efecto resultante de mal rendimiento en el
uso de la cach. na posible solucin alternativa sera prescindir de las cachs, siempre &
cuando fuera posible determinar !u patrones de acceso son los !ue definen el acceso a
memoria & reali#ar la segmentacin en consecuencia.
( Carlos )imne# de Parga B
CP%
CP%
!emoria 1
!emoria 1
!emoria #
!emoria #
!emoria n
!emoria n
Cac?
Cac?
Captulo 1 Introduccin a los Computadores Paralelos
5. @aAonom,a de Fl-nn
Para clasificar las ar!uitecturas paralelas e,isten diferentes clasificacionesE aun!ue
una de las m"s utili#adas es la !ue defini el ingeniero :ichael ). 8l&nn en *@B. & es
conocida como la ta,onoma de 8l&nn.
Esta clasificacin distingue ar!uitecturas multiprocesadores de acuerdo a dos
dimensiones independientes$ datos e instrucciones, donde cada una de estas dimensiones
puede tener slo dos posibles estados$ simple 5single6 & mBltiple 5multiple6.
% continuacin e,aminaremos cada una de estas clasificaciones.
5.1 Cingle InstructionD Cimple 1ata =CIC1>
Dentro de esta categora se encuadran la ma&ora de los computadores secuenciales
disponibles actualmente$ PC, Estaciones de Frabajo & antiguos :ainframe. +as instrucciones
se ejecutan secuencialmente, pero pueden utili#ar segmentacin & m"s de una unidad de
c"lculo. 0iempre har"n uso de una 'nica unidad de control !ue gobierna todas las
instrucciones. Es traducido como instruccin 'nica, datos 'nicos.
Figura 1.9 %r!uitectura 0/0D

+a secuenciacin de las instrucciones es producida por cada pulso de reloj, haciendo
!ue la CP obtenga un dato o un instruccin de memoria para su ejecucin secuencial.
?
%nidad de Control
%nidad de Control
%nidad
Procesamiento
%nidad
Procesamiento
Instrucciones
Flu4o de datos
Captulo 1 Introduccin a los Computadores Paralelos
%s, de esta manera si las instrucciones se ejecutaran en el orden de la figura *.@
Load x
Load y
! x " y
#tore
Procesador
Figura 1.: Ejemplo ejecucin de instrucciones en 0/0D
5.# Cingle InstructionD !ultiple 1ata =CI!1>
Este modelo se ilustra en la figura *.*>. Es un tipo de ar!uitectura paralela donde
todas las unidades ejecutan la misma instruccin en un ciclo de reloj & cada unidad opera
sobre una parte diferente de los datos. Esta ar!uitectura es especialmente apropiada para
problemas de procesamiento de im"genes & gr"ficos, como es el caso de CD%, !ue
veremos en el captulo siguiente.
0e traduce como instruccin 'nica, datos m'ltiples. En esta clasificacin se
encuadran los procesadores matriciales en los !ue e,isten m"s de una unidad de
procesamiento trabajando sobre flujos de datos distintos, pero ejecutando la misma
instruccin proporcionada por una 'nica unidad de control como vemos en la figura *.*>$
Figura 1.1E %r!uitectura 0/:D
( Carlos )imne# de Parga @
@
i
e
m
p
o
%nidad de Control
%nidad de Control
%nidad
Procesamiento 1
%nidad
Procesamiento 1
Instrucciones
%nidad
Procesamiento #
%nidad
Procesamiento #
%nidad
Procesamiento +
%nidad
Procesamiento +
Flu4o de datos
Flu4o de datos
Instrucciones
Captulo 1 Introduccin a los Computadores Paralelos
Por lo tanto, un ejemplo de orden de ejecucin de las instrucciones !ueda tal como se
muestra en la siguiente figura$
Load x$1%
Load y$1%
$1%! x$1% " y$1%
#tore $1%
Procesador 1
Load x$2%
Load y$2%
$2% ! x$2% " y$2%
#tore $2%
Procesador #
Load x$n%
Load y$n%
$n% ! x$n% " y$n%
#tore $n%
Procesador &
Figura 1.1E Ejemplo de ejecucin en ar!uitectura 0/:D
5.& !ultiple InstructionD Cimple 1ata =!IC1>
Es la traduccin de instrucciones m'ltiples, datos 'nicos. Esta organi#acin se
caracteri#a por el hecho de la e,istencia de varias unidades de procesamiento cada una
ejecutando una instruccin diferente pero sobre el mismo dato. Es una ar!uitectura terica &
no se conoce ninguna materiali#acin de esta categora.
Figura 1.11 %r!uitectura :/0D
*>
@
i
e
m
p
o
%nidad de Control 1
%nidad de Control 1
%nidad
Procesamiento 1
%nidad
Procesamiento 1
%nidad
Procesamiento #
%nidad
Procesamiento #
%nidad
Procesamiento +
%nidad
Procesamiento +
%nidad de Control #
%nidad de Control #
%nidad de Control +
%nidad de Control +
Instrucciones
Instrucciones
!
i
s
m
o

/
l
u
4
o

d
e

d
a
t
o
s
Instrucciones
Captulo 1 Introduccin a los Computadores Paralelos
De esta forma, un ejemplo !ue clarifica el flujo de instrucciones sera el siguiente$
Load x$1%
$1%! x$1% " 1
#tore $1%
Procesador 1
Load x$1%
$2% ! x$1% " 2
#tore $2%
Procesador #
Load x$1%
$n% ! x$1% " n
#tore $n%
Procesador &
Figura 1.1E Ejemplo de ejecucin en ar!uitectura :/0D
5.5 !ultiple InstructionD !ultiple 1ata =!I!1>
/nstrucciones m'ltiples, datos m'ltiples. Dentro de esta categora se encuadran la
ma&ora de sistemas multiprocesadores & multicomputadores, donde cada programa se
ejecuta en cada unidad de procesamiento. Esta ar!uitectura implica una coordinacin entre
procesadores, puesto !ue todos los flujos de memoria se obtienen de un espacio compartido
para todos ellos. +os procesadores en esta ar!uitectura trabajan de manera independiente.
Por ejemplo, dos procesadores podran estar reali#ando la Fransformada ="pida de
8ourier, mientras otro reali#a la salida gr"fica. Esto es lo !ue habitualmente se denomina
descomposicin de control. %un!ue no debemos pasar por alto la descomposicin de datos,
en la !ue los datos del problema se reparten entre los distintos procesadores & todos ejecutan
el mismo programa sobre la #ona de datos !ue se le ha asociado. Gste modelo es mucho m"s
potente !ue las ar!uitecturas 0/:D.
+a gran ventaja de los sistemas 0/:D con respecto a los :/:D es !ue necesitan
menos hardware, &a !ue slo re!uieren una unidad de control. +os sistemas :/:D son m"s
independientes & ejecutan cada uno de ellos una copia del programa & del 0istema
Cperativo. %dem"s de esto, los sistemas 0/:D necesitan menos tiempo de inicio para las
comunicaciones entre procesadores, debido a !ue son transferencias entre registros de los
procesadores.
Como conclusin, aun!ue los sistemas 0/:D aparentemente sean m"s baratos !ue
los :/:D, esto no es cierto, pues los sistemas :/:D pueden construirse con ordenadores
convencionales de baja potencia.
( Carlos )imne# de Parga **
@
i
e
m
p
o
Captulo 1 Introduccin a los Computadores Paralelos
Figura 1.11 %r!uitectura :/:D
Load al&a
Load 'eta
! al&a " 'eta
#tore
Procesador 1
r ! t " (
(++
#tore r
#tore (
Procesador #
a ! ' ) c
d ! ' " 3
epsilon ! s*rt$d%
#tore epsilon
Procesador &
Figura 1.1# Ejemplo de ejecucin en ar!uitectura :/:D
*.
%nidad de Control 1
%nidad de Control 1
%nidad
Procesamiento 1
%nidad
Procesamiento 1
%nidad
Procesamiento #
%nidad
Procesamiento #
%nidad
Procesamiento +
%nidad
Procesamiento +
%nidad de Control #
%nidad de Control #
%nidad de Control +
%nidad de Control +
Instrucciones
1atos
1atos
Instrucciones
@
i
e
m
p
o
Captulo 1 Introduccin a los Computadores Paralelos
5. Organi<acin del espacio de direcciones de memoria
Dependiendo de cmo se organice el sistema de almacenamiento primario, los
procesadores se comunicar"n de diferentes formas. %tendiendo a esta organi#acin, se
podr"n encontrar las siguientes ar!uitecturas$
5.1 Cistemas de memoria compartida o multiprocesadores
Estos sistemas se caracteri#an por!ue los procesadores comparten fsicamente la
memoria & acceden al mismo espacio de direcciones de memoria. Por ejemplo, si un
procesador escribe en una de las direcciones de memoria, otro procesador del mismo sistema
puede acceder a esa misma posicin directamente. Consecuentemente, los cambios
reali#ados por un procesador en la memoria com'n son visibles por los otros procesadores
del sistema a travs de una red de interconexin, como puede verse en la siguiente figura$
Figura 1.1& Es!uema b"sico de los sistemas con memoria compartida
%hora bien, dentro de estos sistemas de memoria compartida podemos encontrar otra
clasificacin dentro de ella. %tendiendo a la duracin del tiempo de acceso a la memoria.
%s nos encontramos con una nueva clasificacin$
0istemas de acceso uniforme a memoria 5:%6
0istemas de acceso no uniforme a memoria 51:%6
Estos sistemas consiguen una mejora del rendimiento a2adiendo a cada procesador
una memoria local, donde se almacena el cdigo !ue ejecuta cada uno, as como los datos
!ue no son compartidos entre procesadores del sistema & por tanto son locales a ese
procesador. De esta forma se consigue evitar un e,ceso de intercambio de informacin en la
red de intercone,in para buscar cdigo & datos locales, & consecuentemente un mejora de
la eficacia.
( Carlos )imne# de Parga *3
R
e
d

d
e

i
n
t
e
r
c
o
n
e
A
c
i

n
!
e
m
o
r
i
a

1
!
e
m
o
r
i
a

+
P
r
o
c
e
s
a
d
o
r

1
P
r
o
c
e
s
a
d
o
r

+
Captulo 1 Introduccin a los Computadores Paralelos
5.1.1 Cistemas de acceso uni/orme a memoria =%!">
0on las siglas de niform :emor& %ccess. Estos sistemas se caracteri#an por
tener igual tiempo de acceso a memoria, adem"s los procesadores se caracteri#an por ser
idnticos.
+a ma&ora de los sistemas de memoria compartida se distinguen por incorporar una
memoria cach local en cada procesador , consiguiendo por tanto un incremento en el ancho
de banda entre el procesador & la memoria local. +os as llamados CCH:% 5Cache
Coherent :%6 son sistemas :% donde la coherencia de cach
*
debe intentar !ue si un
procesador modifica una direccin de memoria, todos los procesadores del sistema deben
estar informados al respecto. +a figura *.*3 es un ejemplo de ar!uitectura :%.
na de las limitaciones de la ar!uitectura :% es la escalabilidad & normalmente
encontramos estos sistemas con un n'mero de procesadores comprendido entre *D & 3.E
aun!ue algunos sistemas han logrado alcan#ar hasta los D7 procesadores como el 0un
E*>>>>. 0e ha estudiado !ue si saturamos al sistema de procesadores, no se conseguir"
ninguna mejora. %ctualmente, los sistemas :% se utili#an para la construccin de
ar!uitecturas multiprocesador de bus compartido con un n'mero reducido de procesadores.
Estos sistemas son com'nmente representados por los multiprocesadores simtricos.
5.1.# Cistemas de acceso no$uni/orme a memoria =+%!">
+os sistemas de acceso noHuniforme a memoria se les denomina tambin como
sistemas de memoria compartida distribuida, o sus siglas en ingls 5+istri'uted #,ared
-emory6. En estos sistemas se consigue una mejora del rendimiento eliminando la memoria
global a la !ue acceden los procesadores, eso s, siempre !ue el tiempo de acceso a la
memoria local sea mu& inferiores al tiempo de acceso por la red de intercone,in. En estas
ar!uitecturas los procesadores no tienen un tiempo igual de acceso a las memorias.
El sistema I0=H* es el primero !ue incorpor coherencia por hardware. % este tipo
de sistemas se le denomin cc1:%, aun!ue tambin se les conoce como
multiprocesadores simtricos escalables.
%ctualmente la ma&ora de los sistemas de ar!uitectura de memoria compartida son
1:%. En este caso no e,iste el problema de la escalabilidad, por lo !ue no es difcil
encontrar sistemas con m"s de A*. procesadores interconectados, incluso hasta ..>7?.
En general 1:% no necesita de mecanismos especiales !ue aseguren !ue los
procesadores interconectados tengan un conocimiento coherente del espacio de direcciones
global, siendo el programador el !ue las controle.
* +a coherencia es dise2ada a nivel hardware
*7
Captulo 1 Introduccin a los Computadores Paralelos


Figura 1.15 %r!uitectura 1:%
5.# Cistemas de memoria distri'uida o multicomputadores
+os sistemas de memoria distribuida se caracteri#an por!ue cada sistema contiene su
propio procesador & su propia memoria, comunic"ndose cada sistema entre s por medio de
paso de mensa.es a travs de una red de computadores. %un!ue este apartado es e,tensible a
una inmensa bibliografa, a!u vamos a e,plicarla de manera superficial, &a !ue no es
materia relacionada con el objetivo del presente libro.
+os sistemas de memoria distribuida pueden ser intercone,iones entre estaciones de
trabajo, Pcs con diferentes sistemas operativos, etc. 1ormalmente suelen interconectarse
en una red +%1 Ethernet a travs de un s(itc, o conmutador.
Puesto !ue la latencia de la red puede ser alta, ha& !ue tener en cuenta el
factor de eficiencia llamado granularidad del computador paralelo. Este factor es la
relacin o cociente entre el tiempo re!uerido para reali#ar una operacin '/sica de
comunicacin & el tiempo re*uerido para realiar una operacin '/sica de c/lculo de los
procesos. De esta forma, la estrategia de programacin de los sistemas de memoria
distribuida debe tener siempre como objetivo disminuir la granularidad de las
comunicaciones, es decir, minimi#ar el n'mero de mensajes & ma,imi#ar el tama2o.
Cuando se combinan los sistemas :/:D con programacin paralela de paso de
mensajes se le denomina sistemas multicomputadores.
( Carlos )imne# de Parga *A
R
e
d

d
e

i
n
t
e
r
c
o
n
e
A
c
i

n
!emoria 1
!emoria +
Procesador 1
Procesador +
Captulo 1 Introduccin a los Computadores Paralelos
Figura 1.16 %r!uitectura distribuida
/gualmente, los sistemas de memoria distribuida o multicomputadores pueden ser
computadores con m'ltiples CPs comunicadas por un bus de datos o bien m'ltiples
ordenadores interconectados a travs de un red +%1 o la misma /nternet, siempre !ue la
velocidad sea m"s o menos r"pida.
En el primer caso hablaremos de sistemas masi0amente paralelos 5:PP6, & en el
segundo de clusters1 como podra ser una coleccin de estaciones de trabajo, junto con PCs
interconectados por una red de comunicaciones r"pida.
+os clusters pueden ser de dos clases$
2eo(ul&$ Cada computador del cluster est" dedicado e,clusivamente al mismo.
345$ =ed de estaciones de trabajo. 0us computadores no est"n e,clusivamente
dedicados al cluster.6
+os sistemas Beowulf est"n compuestos por nodos minimalistas
.
interconectados en
una red de comunicaciones de bajo coste, cu&a topologa est" orientada a la resolucin de un
determinado problema de computacin, & donde cada nodo se dedica de manera e,clusiva a
procesos del supercomputador.
+a red de intercone,in de los sistemas +O0s de redes de intercone,in de
estaciones de trabajo suelen utili#arse s(itc,es1 mientras !ue en los 2eo(ul& la intercone,in
se reali#a de manera barata, por medio de tarjetas Ethernet con un conector =)H7A & cable
Ethernet *>>. Por 'ltimo, la programacin en 2eo(ul& se caracteri#a por!ue es mu&
dependiente de la ar!uitectura & siempre se utili#a el modelo de programacin paralela
basada en paso de mensajes.
. +os nodos minimalistas constan de una placa base, CP, memoria & dispositivos de EJ0.
*D
PC *
PC *
PC .
PC .
PC 3
PC 3
PC 7
PC 7
PC A
PC A
Red de interconeAin
Red de interconeAin
Captulo 1 Introduccin a los Computadores Paralelos
5.& Conclusin
+a ventaja de los clusters con respecto a las ar!uitecturas como 1:% es !ue es
sencillo & poco costoso construir un sistema paralelo con varios ordenadores interconectados
en red, de forma r"pida & con alto rendimiento en computacin. El 'nico problema estriba en
el modelo de programacin$ mientras !ue en los sistemas de memoria compartida es solo
necesario establecer una pocas directivas al compilador, en los sistemas de memoria
distribuida ha& !ue programar e,plcitamente todas las comunicaciones.
%tendiendo a las diferentes clasificaciones e,puestas anteriormente & siguiendo la
taxonoma de 7lynn, puede dise2arse un breve diagrama a modo de resumen$
Figura 1.17 Diagrama de clasificacin de las ar!uitecturas paralelas
3
3 :PP$ Procesadores :asivamente Paralelos
0:P$ :ultiprocesadores 0imtricos
( Carlos )imne# de Parga *B
"r.uitecturas
paralelas
"r.uitecturas
paralelas
CI!1
CI!1
!I!1
!I!1
!emoria
distri'uida
!emoria
distri'uida
!emoria
compartida
!emoria
compartida
C!P
C!P
Cluster
Cluster
!PP
!PP
+O0
+O0
BeoFul/
BeoFul/
Captulo 1 Introduccin a los Computadores Paralelos
6. !odelos de programacin paralela
na ve# vistas las diferentes ar!uitecturas en las !ue se basan los computadores
paralelos & su organi#acin de memoria, es ahora factible conocer a grandes rasgos los
diferentes modelos m"s com'nmente usados de programacin en estos sistemas.
Para comen#ar, los modelos de programacin e,isten como una abstraccin sobre las
ar!uitecturas hardware & software. 0in !ue decir !ue estos modelos se pueden combinar
para crear otros modelos basados en sus antecesores, &, aun!ue no lo pare#ca, los modelos
!ue veremos a continuacin no son especficos de una determinada ar!uitectura.
Ku modelo es el m"s adecuado para usar es a menudo determinado por cual es m"s
adecuado para el dominio del problema & cual es preferible por el programador. 1o ha&
ning'n modelo mejor, aun!ue ciertamente e,isten unos modelos mejores !ue otros.
6.1 !odelo de memoria compartida
En este modelo las tareas comparten un espacio com'n de direcciones en la !ue leen
& escriben de manera asncrona, pudiendo sincroni#arlas mediante el uso de sem"foros
7
para
evitar com'n a memoria compartida.
na ventaja de este modelo es !ue el programador no tiene nocin de la propiedad
de los datos, por lo !ue no es necesario especificar la comunicacin entre tareas & el trabajo
para el programador se simplifica. 0in embargo, es importante recalcar !ue es m"s difcil
entender & controlar la localidad de los datos, por lo !ue esto puede afectar al rendimiento.
%ctualmente no e,isten actualmente implementaciones de este modelo
6.# !odelo de t?reads =?ilos>
En el modelo de threads, un 'nico proceso puede tener m'ltiples vas concurrentes
de ejecucin.
7 Leneralmente se implementa con la primitiva locM
*?
Captulo 1 Introduccin a los Computadores Paralelos
L,nea Instruccin
* call procedimiento*
. call procedimiento.
3 for i N * to n
7 O
A ,5i6 N f5i J .6
D &5i6 N,5i6 P pi
B Q
? call procedimiento3
Programa prog.out
Figura 1.8 Ejemplo de programacin con modelo de threads
Como podemos ver el programa prog.out es ejecutado en el sistema operativo & obtiene
los recursos del sistema !ue le son necesarios. Prog.out lleva cierta ejecucin en serie &
despus crea un n'mero determinado de threads 5hilos6 !ue son gestionados por el sistema
operativo & pueden verse como llamadas a procedimientos. Cada thread contiene sus datos
locales, aun!ue tambin comparten sus recursos, mientras se benefician de la memoria
global &a !ue comparten el espacio de memoria de Prog.out.
+os threads de prog.out utili#an la memoria global para comunicarse, &
consecuentemente necesitan alg'n mtodo de sincroni#acin para asegurarse !ue m"s de un
thread no est escribiendo en la misma posicin de memoria.
El modelo de threads se le asocia com'nmente al modelo de ar!uitectura de memoria
compartida & programacin concurrente en sistemas operativos.
+as implementaciones m"s conocidas de threads son las siguientes$
@?reads POCI;$
Est" basado en libreras & en el lenguaje C.
0e les referencia como Pthreads.
El paralelismo se gestiona de forma e,plcita, por lo !ue implica !ue el programador
ponga atencin en los detalles del cdigo.
( Carlos )imne# de Parga *@
@1 @#
@&
@
i
e
m
p
o
Captulo 1 Introduccin a los Computadores Paralelos
Open!P
Como CD%, est" basado en directivas del compilador, por lo !ue puede ser usado
para generar cdigo serie.
+a %P/ est" implementada para los lenguajes 8ortran & CRR
:ultiplataforma & escalable
Leneralmente se utili#a para programar ar!uitecturas de memoria compartida
int main(int argc, char *argv[]) {
const int N = 100000;
int i, a[N];

#pragma omp parallel for
for (i = 0; i < N; i)
a[i] = ! * i;

ret"rn 0;
#
Cdigo 1.1 Ejemplo en Cpen:P !ue inicia un arra& en paralelo
6.& !odelo de paso de mensa4es
En este modelo las tareas utili#an su propia memoria local durante la computacin.
:'ltiples tareas pueden residir en la misma m"!uina fsica &Jo a travs de un n'mero de un
n'mero de m"!uina arbitrario. De esta manera, las tareas intercambian sus datos entre ellas
por mensajes de comunicacin de envo & recibimiento. +as transferencias de datos
re!uieren cooperacin entre las primitivas
A
implementadas en cada proceso. %s si se lleva a
cabo un operacin de envo en una m"!uina, re!uiere !ue en otra m"!uina e,ista la
primitiva correspondiente de recibimiento.
Figura 1.9 Ejemplo del modelo de paso de mensajes
A Estas primitivas suele denominarse send & recv
.>
PC "l/a
PC "l/a
@area "
Datos
@area B
Datos
PC Beta
PC Beta
@area C
Datos
@area 1
Datos
Red
Red
send()
send()
recv()
recv()
Captulo 1 Introduccin a los Computadores Paralelos
=especto a la implementacin, el modelo de paso de mensajes consta de un conjunto de
libreras !ue se enla#an en el compilador de la plataforma especfica donde se implemente el
cdigo fuente & !ue contienen la implementacin de la %P/ & primitivas de paralelismo.
Cuando se dise2a una aplicacin con paso de mensajes es el programador el !ue se
encarga de determinar todo el paralelismo.
Desde los a2o ochenta han habido muchas implementaciones de este modeloE aun!ue
las m"s conocidas han sido P3!
7
5Parallel 4irtual :achine6 & !PI
8
5:essage Passing
/nterface6.
6.5 !odelo de paralelismo a ni2el de datos
En el modelo de paralelismo de datos se caracteri#a por su enfo!ue en las
operaciones sobre conjuntos de datos. Estos datos se suelen organi#ar en estructuras de datos
tales como arra&s o cubos 5arra&s tridimensionales6. De esta forma, un determinado n'mero
de tareas trabajan colectivamente sobre una parte diferentes de esa estructura de datos. Este
modelo ser" aplicado sistem"ticamente a lo largo de los captulos dedicados a la
programacin en CD%.
Como vemos en la figura *.@, la caracterstica principal es !ue la tareas siempre aplican
la misma operacin en la parte !ue les corresponde de la estructura de datos.
for i N * to *> for i N ** to .> for i N .* to 3>
O O O
S5i6 N 95i6 P Pi S5i6 N 95i6 P Pi S5i6 N 95i6 P Pi
S5i6RR S5i6RR S5i6RR
Q Q Q
@area " @area B @area C
Figura 1.: Ejemplo del modelo de paralelismo de datos
D http$JJwww.csm.ornl.govJpvmJpvmThome.html
B http$JJwww.mcs.anl.govJresearchJprojectsJmpiJ
( Carlos )imne# de Parga .*
*
Estructura de datos X
*> ** .> .* 3>
Captulo 1 Introduccin a los Computadores Paralelos
En las ar!uitecturas de memoria compartida, todas la tareas pueden tener acceso a la
estructura de datos a travs de la memoria global. En las ar!uitecturas de memoria
distribuida la estructura de datos es dividida & reside en peda#os en la memoria local de cada
tarea.
6.6 Otros modelos
E,isten otros modelos de programacin paralela, aun!ue los m"s com'nmente
usados son los !ue se han e,plicado en los apartados anteriores. % continuacin veremos dos
modelos de entre los m"s importantes !ue son tambin com'nmente utili#ados en
ar!uitecturas de memoria distribuida.
Cingle Program !ultiple 1ata =CP!1>
En este modelo de programacin paralela, al arrancar una aplicacin se lan#an 1
copias del mismo programa 5procesos6. Estos procesos no avan#an sincroni#ados instruccin
a instruccin sino !ue la sincroni#acin debe ser reali#ada e,plcitamente.

Figura 1.1E :odelo 0P:D ejecutado en la misma plataforma
..
Programa
Programa
@area 1
4ecutando programa
@area 1
4ecutando programa
@area #
4ecutando programa
@area #
4ecutando programa
@area &
4ecutando programa
@area &
4ecutando programa
Compilador
Compilador
Captulo 1 Introduccin a los Computadores Paralelos
En cual!uier momento, las tareas pueden ejecutar la misma o diferentes instrucciones
con el mismo programa & pueden usar diferentes datos.
!ultiple Program !ultiple 1ata =!P!1>
En esta metodologa se escribe un programa propio & diferente para cada procesador. En
el enfo!ue maestro)escla0o un procesador ejecuta un programa 5proceso maestro6 !ue
posteriormente arrancar" los dem"s procesos 5procesos esclavos6. El arran!ue de esos
procesos es relativamente costoso desde una perspectiva computacional. Como es lgico, las
tareas pueden usar diferentes datos.
Figura 1.11 :odelo :P:D ejecutado en la misma plataforma
( Carlos )imne# de Parga .3
Programa
"l/a
G
Programa
"l/a
G
Programa
Omega
H
Programa
Omega
H
Compilador
Compilador
@area 1
4ecutando G
@area 1
4ecutando G
@area #
4ecutando H
@area #
4ecutando H
@area &
4ecutando G
@area &
4ecutando G
Captulo 1 Introduccin a los Computadores Paralelos
7. Paradigmas algor,tmicos de paraleli<acin
% continuacin se e,pondr"n las diferentes estrategias algortmicas para abordar un
problema de programacin paralela$
7.1 Fases paralelas
0e basa en la sucesin de un n'mero arbitrario de fases para llegar a la solucin del
problema, donde cada fase consta de dos etapas$ c"lculo e interaccin.
Figura 1.1# 8ases paralelas
Durante la etapa de c"lculo, cada tarea reali#a sus operaciones independientemente.
Cuando se termina esta etapa se pasa a la etapa de interaccin, en la !ue se sincroni#an las
tareas con primitivas con el objetivo del intercambio de informacin & resultados entre
tareas. 8inalmente, despus de la etapa de sincroni#acin se prosigue en la siguiente fase.
.7
Fase 1
Tarea 1
(Clculo)
Tarea 2
(Clculo)
Tarea
(Clculo)
Cincroni<acin
Etapa
c"lculo
Etapa
interaccin
Fase 2
Tarea 1
(Clculo)
Tarea 2
(Clculo)
Tarea
(Clculo)
Cincroni<acin
Etapa
c"lculo
Etapa
interaccin
Fase 1
Tarea 1
(Clculo)
Tarea 2
(Clculo)
Tarea
(Clculo)
Cincroni<acin
Etapa
c"lculo
Etapa
interaccin
Fase 2
Tarea 1
(Clculo)
Tarea 2
(Clculo)
Tarea
(Clculo)
Cincroni<acin
Etapa
c"lculo
Etapa
interaccin
Fase !
Tarea 1
(Clculo)
Tarea 2
(Clculo)
Tarea
(Clculo)
Cincroni<acin
Etapa
c"lculo
Etapa
interaccin
Tarea 1
(Clculo)
Tarea 2
(Clculo)
Tarea
(Clculo)
Cincroni<acin
Etapa
c"lculo
Etapa
interaccin
Captulo 1 Introduccin a los Computadores Paralelos
7.# Cegmentacin =pipeline>
+as tareas implicadas en el paralelismo se comportan como etapas de una
segmentacin virtual 5de manera parecida a las ar!uitecturas segmentadas6 en la !ue los
datos avan#an continuamente, por lo !ue la ejecucin de las etapas se solapar"n sobre los
datos de la carga de trabajo.
Figura 1.1& 0egmentacin
7.& 1i2ide - 2encer(s
+a carga de trabajo es dividida por los padres en los sucesivos hijos, !ue ha su ve#
vuelven a dividir la carga de trabajo. Por 'ltimo, el proceso padre es el encargado de recoger
todos los resultados parciales de los hijos & combinarlos para dar un resultado final. Este
mtodo tambin se le denomina arborescente, por su descomposicin arbrea.
Figura 1.15 Divide & vencer"s
( Carlos )imne# de Parga .A
@area 1
@area 1
@area #
@area #
@area +
@area +
Flu"o de datos
@area #
@area #
@area &
@area &
@area 5
@area 5
@area 8
@area 8
@area 6
@area 6
@area 7
@area 7
@area 1
@area 1
Creacin & particin =etorno de resultados
Captulo 1 Introduccin a los Computadores Paralelos
7.5 !aestro$escla2o =?ost$node>
En este paradigma, la tarea maestra reali#a la parte secuencial del algoritmo paralelo
& lan#a sus tareas esclavas, !ue ejecutan de manera paralela la carga de trabajo !ue
representa el problema.
Figura 1.16 :aestroHesclavo
Este paradigma est" basado en tres fases. +a primera se encarga de la iniciali#acin
de los grupos de procesos & la distribucin de la carga de trabajo. +a segunda fase se encarga
del c"lculo del problema en s, & la 'ltima se encarga de la recopilacin & visuali#acin de la
solucin.
.D
!aestro
!aestro
scla2o 1
scla2o 1
scla2o #
scla2o #
scla2o &
scla2o &
scla2o +
scla2o +
Captulo 1 Introduccin a los Computadores Paralelos
8. Bre2e ?istoria de la computacin paralela
+a historia de la computacin paralela se encuentra mu& entrela#ada con la propia
historia de la computacin en general. 0i cierto es !ue los orgenes de la computacin &a se
remontan a tiempos pretritos, por ejemplo, con el invento del "baco, en el caso de la
computacin paralela sus inicios se podra establecer en torno a mediados del siglo 99 con
el desarrollo del primer computador de segunda generacin transistori#ado.
En *@A?, Lill &a escribi sobre las bases de la programacin paralela & una a2o despus
-olland plante la posibilidad pudiera ejecutar un n'mero determinado de programas
simult"neamente. En *@D3 Conwa& describe el dise2o de un computador paralelo su
programacin.
Pero no fue hasta *@?* cuando se present el primer sistema paralelo comercial, el
Butter/l-, distribuido por BB Com#uters $dvanced. Capa# de dividir su trabajo entre .AD
procesadores, en concreto microprocesadores !otorola %&''', !ue se conectaban a travs
de una red multietapa con memorias de A>>Ib&tes por procesador. 0e consiguieron vender
3A m"!uinas, la ma&ora a universidades & centros de investigacin.
En los a2os ochenta & principios de los noventa comen# la denominada era de la poca
dorada de la programacin paralela. Particularmente en el paralelismo a nivel de datos. Entre
las ar!uitecturas m"s destacadas caben citar la Connection !ac?ineD !asPar & Cra-, as
como verdaderos supercomputadores, increblemente e,ticos, poderosos & mu& costosos.
Esto deriv en lo !ue se denomin poca oscura de la computacin paralela, puesto !ue fue
difcil vender estos e!uipos tan potentes. +a industria & los centros de investigacin se
vieron for#ados a detener sus actividades. +a solucin fue reempla#ar las costosas m"!uinas
masivamente paralelas por clusters, grids, etc.
En los 'ltimos a2os el rendimiento de los computadores paralelos ha aumentado
significativamente. El 'ltimo fenmeno es la democrati#acin de la programacin paralela,
con la llegada de las LPs multin'cleo a todos los hogares.
Figura 1.17 Evolucin de la computacin paralela
( Carlos )imne# de Parga .B
Captulo 2 Arquitectura de CUDA
2
Arquitectura de CUDA
1. Introduccin
Una vez entendidos los conceptos bsicos de paralelismo explicados en el captulo
anterior, podemos comenzar a desgranar con detalle los entresijos de la tecnologa CUDA de
Nvidia.
Comenzaremos en este captulo con la estructura que deine un sistema CUDA, sus
n!cleos, memoria " su modelo de abstracci#n del paralelismo a nivel de $ard%are.
&n noviembre de '(() Nvidia introduce la Arquitectura Unificada *CUDA+ con la
presentaci#n de su modelo ,e-orce ..((. Desde entonces $an aparecido en el mercado
dierentes modelos tambi/n compatibles tales como los modelos 0esla " 1uadro. &stos
modelos eran mu" similares, dierencindose principalmente en el anc$o de banda del bus,
la cantidad de memoria, lo n!cleos " la cantidad de registros.
2as nuevas ,3Us de Nvidia se constru"eron a partir de la replicaci#n de un bloque
constructivo bsico, como acelerador con memoria integrada. 2a principal ventaja de las
nuevas ,3Us multin!cleo se basan una jerarqua de threads mapeados sobre el $ard%are,
que consiguen un paralelismo transparente " eiciente. Adems, permite creaci#n,
planiicaci#n " ejecuci#n transparente de miles de threads de manera concurrente.
Una de las ventajas de las ,3Us multin!cleo es la liberaci#n de la C3U de carga de
trabajo que pueden ser delegadas especicamente a la tarjeta grica. De esta orma, se
consigue ma"or rendimiento para ciertas tareas, as, por ejemplo, podemos comprobar el uso
de esta tecnologa en los siguientes tipos de problemas4
5ultiplicaci#n de matrices densas
0ratamiento digital de se6ales, especialmente vdeo
Clculo de potencial el/ctrico
7esoluci#n de ecuaciones polinomiales
Aunque parezca que todos los tipos de problema o algoritmos se podran adecuar a
una implementaci#n en CUDA, esto no es cierto, pues se considera una alacia pensar que
todos los algoritmos son susceptibles de adaptarse al paralelismo de las ,3Us. As, mientras
que las C3Us se orientan a optimizar la ejecuci#n de aplicaciones de prop#sito general, las
,3Us son dedicadas a obtener un ma"or rendimiento pico " de procesamiento grico.
Actualmente, podemos encontrar ,3Us con un rendimiento aproximado de unos
8 Carlos 9im/nez de 3arga :
Captulo 2 Arquitectura de CUDA
;((,lops
:
.
3uesto que las ,3Us liberan a la C3U de carga de trabajo grica, esto $a propiciado
un auge en el mundo de la tecnologa de videojuegos, " a$ora mismo las ,3Us multin!cleo
se pueden encontrar en ordenadores de sobremesa o servidores integradas en la placa o
como tarjetas externas.
Como veremos en pr#ximos captulos captulo las tarjetas Nvidia estn bien
integradas con las tecnologas de sot%are grico como son Direct< " =pen,2.
3or !ltimo, " puesto que las ,3Us se estn volviendo cada vez ms rpidas,
presentaremos una grica de la evoluci#n de las tarjetas de vdeo en esta !ltima d/cada,
antes de entrar en los recovecos del laberinto de CUDA.
Figura 2.1 &voluci#n de las tarjetas gricas Nvidia
: :(
>
operaciones en punto lotante
'
Ene 2003 Jun 2003 Abr 2004 May 2005 Nov 2005 Mar 2006 Nov 2006
0
50
100
150
200
250
300
350
Nvidia
Intel Core2 Duo




G
F

!
"
#
$
%
Captulo 2 Arquitectura de CUDA
2. Entrando en la GPU
,3U son las siglas en ingles que se establecieron como acr#nimo de Graphics
Processing Unit o traducido al castellano, Unidad Procesamiento Grfico. 5uc$o $a llovido
desde los inicios de la inormtica grica, desde el primer $ard%are monocromtico
integrado en las placas base $asta las modernas tarjetas como las que trata este libro. ?u
aparici#n no es exclusiva del 3C, sino que tambi/n podemos encontrar tarjetas en una gran
variedad de sistemas como videoconsolas, 3DAs " tel/onos m#viles.
2as actuales ,3Us de Nvidia se caracterizan por su c$ips con tecnologa multithread
masivo en multincleo &n el caso del modelo 0esla el n!mero de procesadores escalares
llega a :'., con :'.((( t$reads concurrentes " un rendimiento sostenido de @A( ,-2=3?.
&sta tecnologa no $a pasado desapercibida a los cienticos e ingenieros donde $an
conseguido incrementar en :(( veces su potencia de clculo.
2a caracterstica principal de la programaci#n en CUDA es que permite combinar la
implementaci#n de c#digo serie en el host
2
con la implementaci#n de c#digo paralelo en el
dispositivo. De esta manera conseguiremos entrelazar ejecuciones serie con ejecuciones
paralelas en los !ernel
Figura 2.2 5odelo de ejecuci#n en CUDA
' Nos reeriremos al host como el sistema del usuario donde reside la C3U " al dispositivo como la ,3U Nvidia
8 Carlos 9im/nez de 3arga B
Host
Cdigo serie
Kernel paralelo
1
Dispositio
Host
Cdigo serie
Dispositio
Kernel paralelo
2
Captulo 2 Arquitectura de CUDA
2a ejecuci#n en la parte del dispositivo se realiza por un conjunto inito de t$reads
paralelos que act!an sobre una parte dierente de los datos. De esta orma podemos deinir
como kernel a un conjunto determinado de muc$os t$reads concurrentes, donde s#lo un
!ernel es ejecutado al mismo tiempo en el dispositivo, " muc$os t$reads participan el la
ejecuci#n del !ernel. Cada t$read tiene su propio identiicador para poder realizar un
paralelismo transparente sobre los datos. 2os t$reads en CUDA pueden ser de dos clases4
"hread fsicos# ?on los t$reads de la ,3U Nvidia, donde la creaci#n " cambio de
contexto de los t$reads de la ,3U son esencialmente libres.
"hreads virtuales4 Donde, por ejemplo, un n!cleo de la C3U podra ejecutar
m!ltiples t$reads CUDA.
( : ' B @ ; ) A
Figura 2.! &jecuci#n paralela de un grupo . de t$reads
Como puede observarse en la igura '.B, los . t$reads lanzados realizan un
procesamiento sobre la zona respectiva de los datos a que cada t$read identiica,
almacenando la salida en cada zona de datos respectiva a cada identiicador.
2os t$reads se pueden agrupar en bloques, de esta orma podemos entender a un
!ernel como un grid de bloques de t$reads. Debemos tener presente que la sincronizaci#n de
t$reads dentro de un bloque debe realizarse con barreras *$arriers+4
salida[threadID] = entrada[threadID];
_syncthreads();
float xscale = salida[threadID 1];
&n este ejemplo, los t$reads implicados en la parte *:+, despu/s de realizar su
procesamiento deben esperar $asta que todos los t$reads de su grupo alcancen la primitiva
Cs"nctr$eads, parte *'+, para poder entrar en la nueva parte de procesamiento *B+.
@
Identificador
de thread
(threadID)
salidaDt$readEDF G
procesimiento x .G
entradaDt$readEDF
Ejecucin
paralela
21
!
Captulo 2 Arquitectura de CUDA
Figura 2." ,rid de N bloques de t$reads
Ha" que considerar, a partir de este modelo que mientras los t$reads de dentro de un
bloque s se pueden sincronizar, los bloques de t$reads no permiten sincronizaci#n entre
ellosI aunque la arquitectura de CUDA permite su ejecuci#n en cualquier orden,
concurrentemente o en serie. 3or lo tanto, se considera que existe una barrera de
sincronizaci#n implcita entre dos !ernels lanzados consecutivamente. Como consecuencia,
esta independencia proporciona una gran escalabilidad, donde los grids se escalan
dependiendo del n!mero de n!cleos paralelos.
Figura 2." ,esti#n de la escalabilidad
8 Carlos 9im/nez de 3arga ;
3rocesamiento
paralelo .x
( : ' B @ ; ) A
t
$
r
e
a
d
E
D
3rocesamiento
paralelo .x
( : ' B @ ; ) A
#loque $
3rocesamiento
paralelo .x
( : ' B @ ; ) A
3rocesamiento
paralelo .x
( : ' B @ ; ) A
#loque 1
t
$
r
e
a
d
E
D
3rocesamiento
paralelo .x
( : ' B @ ; ) A
3rocesamiento
paralelo .x
( : ' B @ ; ) A
#loque %
t
$
r
e
a
d
E
D
. . .
Grid con & 'loques
Jloque ( Jloque :
Jloque ' Jloque B
Jloque @ Jloque ;
Jloque ) Jloque A
Dispositio con
2 n(cleos
Jloque ( Jloque :
Jloque B
Jloque @ Jloque ;
Jloque ) Jloque A
&
j
e
c
u
c
i
#
n
Dispositio con
" n(cleos
Jloque '
Jloque ( Jloque : Jloque ' Jloque B Jloque ( Jloque : Jloque ' Jloque B
Jloque @ Jloque ; Jloque ) Jloque A
&
j
e
c
u
c
i
#
n
Captulo 2 Arquitectura de CUDA
7especto a la jerarqua de memoria es imprescindible destacar que existen tres tipos
de memoria que caracterizan la arquitectura CUDA. 2a primera de ellas es la memoria local
dedicada a cada t$read. Ksta es sin duda la parte de la memoria que es privativa de un !nico
t$read " se encuentra dentro del ambiente de la unci#n que implementa el !ernel. &s la
memoria para datos locales " utilizada exclusivamente para operaciones implementadas en
la misma unci#n. &n segundo lugar tenemos la memoria compartida para los t$reads. &ste
tipo de memoria permite que varios t$reads compartan inormaci#n entre ellos cuando se
ejecutan dentro de un mismo !ernel% permitiendo principalmente optimizar el rendimiento.
3or !ltimo tenemos la memoria glo$al reservada para prop#sitos de almacenamientos de
datos de entrada " resultados del !ernel. &n la siguiente imagen podemos distinguir los
dierentes tipos4
Figura 2.) 9erarqua de memoria
)
*+read
,e-oria
local
,e-oria
local
#loque
,e-oria
co-partida
,e-oria
co-partida
. . .
. . .
Kernel $
Kernel 1
L
e
r
n
e
l

s
e
c
u
e
n
c
i
a
l
e
s
,e-oria
glo'al
,e-oria
glo'al
Captulo 2 Arquitectura de CUDA
!. CUDA en pro.undidad
A$ora que $emos visto las caractersticas principales de la arquitectura CUDA,
pasaremos a describir con ms detalle cada una de las partes vistas anteriormente.
3roseguiremos con la estructura de t$reads " bloques de un !ernel. Como $emos
comentado antes, tanto los t$reads como los bloques contienen un identiicador unvoco que
permite distinguirlos durante la ejecuci#n, de esta orma, el programador puede por medio
de los identiicadores decidir sobre qu/ datos trabajar independientemente de los que $agan
otros t$reads. As un programador puede decir sobre qu/ parte de los datos proporcionados
al !ernel debe acceder un t$read cuando se ejecute su porci#n de c#digo que tambi/n
ejecutarn otros t$reads con sus identiicadores.
Como veremos en pr#ximos captulos, los identiicadores de los bloques pueden ser
unidimensionales *:D+ o bidimensionales *'D+, mientras que los identiicadores de los
t$reads puedes ser unidimensionales, bidimensionales o tridimensionales *BD+. &sto
simpliica enormemente el direccionamiento de memoria para datos multidimensionales, por
lo que puede ser mu" !til en procesamiento de imgenes " resoluci#n de problemas
matemticos complejos que impliquen matrices.

Figura 2./ &jemplo de distribuci#n de t$reads " bloques
8 Carlos 9im/nez de 3arga A
Host
Lernel :
Dispositio
Grid 1
Jloque
*(,(+
Joque
*:,(+
Jloque
*',(+
Jloque
*(,:+
Jloque
*:,:+
Jloque
*',:+
Grid 2
#loque 0$112
0$read
*(,(+
0$read
*:,(+
0$read
*',(+
0$read
*(,:+
0$read
*:,:+
0$read
*',:+
0$read
*(,'+
0$read
*:,'+
0$read
*','+
Lernel '
&
j
e
c
u
c
i
#
n
Captulo 2 Arquitectura de CUDA
Con respecto a la distribuci#n de la memoria, jese el lector en la igura '.A4
Figura 2.3 Detalle de la distribuci#n de memoria
Como el lector podr apreciar, existen varias clases de memorias en la arquitectura
de CUDA. &n primer lugar, como puede verse en la igura, existe una estructura de registros
para los prop#sitos del t$read, utilizada para intercambio de datos entre el procesador " la
memoria, as como operaciones escalares. &xisten un total de .:>' registros repartidos entre
los dierentes $loques de threads en ejecuci#n. 2os t$reads pueden leer " escribir en los
.
H45*
H45*
Grid
#loque 0$1$2
7egistros 7egistros
0$read
*(,(+
0$read
*:,(+
5emoria compartida
5emoria
local
5emoria
local
5emoria compartida
5emoria de texturas
5emoria constante
5emoria global
#loque 0$1$2
7egistros 7egistros
0$read
*(,(+
0$read
*:,(+
5emoria compartida
5emoria
local
5emoria
local
5emoria compartida
Captulo 2 Arquitectura de CUDA
registros de prop#sito general con un tiempo de ejecuci#n mu" peque6o. 2a memoria local,
como pude verse tambi/n en la igura, permite el almacenamiento de datos locales del
propio ambiente del !ernel# los t$reads pueden leer " escribir en esta memoria los datos que
le sean necesarios. &n esta memoria privada para cada t$read se almacenan datos para la pila
" las variables locales. 2a memoria compartida, que tiene una capacidad de :) LJ, permite
intercambiar inormaci#n entre los t$reads de un mismo bloque, por ejemplo en operaciones
de reducci&n. &sta memoria tambi/n permite la lectura " escritura desde los t$reads que
pertenecen al mismo bloque.
3or !ltimo tenemos tres tipos de memoria ms extensas " ubicadas en la memoria
D7A5 de la tarjeta. Kstas son la memoria glo$al, con una capacidad de $asta :.; ,J,
permite tanto a los todos los t$reads como al $ost leer " escribir en ella en com!nI la
memoria constante que permite un alto rendimiento " tiene una capacidad de )@ LJ con .
LJ de memoria cac$/ permite a todos los t$reads leer el mismo valor de memoria constante
simultneamente en un ciclo de reloj. &l tiempo de acceso a la memoria constante es similar
al de los registros " s#lo admite lectura desde los t$reads " lecturaMescritura desde el $ost. 2a
memoria de te'turas explota la localidad espacial con vectores de unidimensionales o
bidimensionales " el tiempo de acceso elevado pero menos que el de la memoria global. Al
igual que la memoria constante, s#lo permite lectura desde los t$reads " lecturaMescritura
desde el $ost.
8 Carlos 9im/nez de 3arga >
Captulo 2 Arquitectura de CUDA
". Hard6are de la GPU
2a ,3U CUDA contiene un conjunto de N
B
(treaming )ultiprocessors% donde cada
(treaming )ultiprocessor es un conjunto de . (treaming Processors *(P+ Cada (treaming
)ultiprocessor crea, planiica " ejecuta $asta '@ ,arps
-
pertenecientes a uno o ms bloques
*A). t$reads+. De esta orma, cada ,arp ejecuta una instrucci#n en @ ciclos de reloj.
Figura 2.& Hard%are de la ,3U con CUDA
Como vimos en la igura '.@, cada bloque se asigna a un n!cleo o (treaming
)ultiprocessor% " un (treaming )ultiprocessor asigna a cada bloque los recursos necesarios
*contextos de t$reads, registros, etc.+.
2os (treaming Processors realizan operaciones escalares sobre tipos de datos
simples de enteros " reales de B' bits, as mismo, cada uno ejecuta t$reads independientes,
B &n el dispositivo ,.( $a" un total de :) multiprocesadores
@ Un bloque se divide en grupos de B' t$reads denominados ,arps
:(
GPU
Unidad de
instrucci#n
?3 ?3
?3 ?3
?3 ?3
?3 ?3
7egistros
Cac$/
constante
5trea-ing
-ultiprocessor
?3 ?3
?3 ?3
?3 ?3
?3 ?3
7egistros
5emoria
compartida
Cac$/
constante
5trea-ing
-ultiprocessor
Unidad de
instrucci#n
?3 ?3
?3 ?3
?3 ?3
?3 ?3
7egistros
5emoria
compartida
Cac$/
constante
?3 ?3
?3 ?3
?3 ?3
?3 ?3
7egistros
Cac$/
constante
Unidad de
instrucci#n
?3 ?3
?3 ?3
?3 ?3
?3 ?3
7egistros
5emoria
compartida
Cac$/
constante
?3 ?3
?3 ?3
?3 ?3
?3 ?3
7egistros
Cac$/
constante
5trea-ing
-ultiprocessor
Unidad de
instrucci#n
?3 ?3
?3 ?3
?3 ?3
?3 ?3
7egistros
5emoria
compartida
Cac$/
constante
?3 ?3
?3 ?3
?3 ?3
?3 ?3
7egistros
Cac$/
constante
Cac$/ de texturas Cac$/ de texturas
. . .
D7A, 0Glo'al1 local1 constante 8 -e-oria de te9turas2
PCI Express (PCX)
5trea-ing
-ultiprocessor
Captulo 2 Arquitectura de CUDA
aunque todos los (treaming Processors deberan ejecutar la instrucci#n leda por la Unidad
de .nstrucci&n en cada instante, de esta manera se sigue un modelo de arquitectura ?E50
*(ingle .nstruction )ultiple "hread+, donde un conjunto de t$reads ejecuta las misma
instrucci#n apuntada en el !ernel, explotando el paralelismo de datos, " en menor medida el
de tareas. 2os t$reads son gestionados por el $ard%are sin necesidad del que el programador
realice estas tareas complejas.
8 Carlos 9im/nez de 3arga ::
Captulo 3 Introduccin a la programacin en CUDA
3
Introduccin a la programacin en CUDA
1. Conceptos preliminares
Antes de comenzar nuestro viaje por los mundos de la programacin paralela en
CUDA es necesario tener presentes algunos conceptos bsicos sobre el modo de diseo de
programas con esta tecnologa.
Los programas en CUDA deben estar escritos en lenguaje C, sabiendo de antemano
ue !a" un conjunto de palabras reservadas de#inidas para la programacin en CUDA " ue
slo el compilador podr traducir. $bviamente, aunue la sinta%is de CUDA es bsicamente
C, es posible, " de !ec!o as se !ar en este libro utilizar la ampliacin del lenguaje C&&.
'or eso, si el lector no posee conocimientos previos de estos lenguajes, puede consultar la
bibliogra#a del #inal del libro donde se le proporcionar una variedad de #uentes donde
podr iniciarse en un tiempo prudencial en este lenguaje.
'uesto ue los programas en CUDA estn escritos en lenguaje C es posible intercalar
sentencias con instrucciones propiamente del compilador de CUDA con instrucciones
estndar C(C&&.

Figura 3.1 Compilacin en dos etapas
) Carlos *im+nez de 'arga ,
Cdigo #uente
CUDA
Cdigo #uente
CUDA
-.CC
-.CC
Cdigo
$bjeto
C'U
Cdigo
$bjeto
C'U
Cdigo '/0
Cdigo '/0
1ront 2nd
'/0 a cdigo
espec#ico
'/0 a cdigo
espec#ico
C!ip -vidia
espec#ico
C!ip -vidia
espec#ico
3ac4 2nd
Captulo 3 Introduccin a la programacin en CUDA
2n la #igura 5., se muestra las dos #ases de compilacin de un programa en CUDA.
2l compilador -.CC discriminar entre el cdigo escrito en lenguaje C " C&& " el
lenguaje propiamente de CUDA, generando de esta manera dos salidas6 cdigo muina
para la C'U espec#ica de la aruitectura en la ue trabaja el sistema operativo " cdigo
'/0, ue es un especie de cdigo ensamblador independiente de la muina, generado por
la parte #rontal del compilador de -vidia. 'osteriormente ser traducido para generar
cdigo muina espec#ico de cada aruitectura de 7'U CUDA.
De esta manera podemos de#inir la estructura de programacin en CUDA como se
muestra en la #igura 5.8.
Figura 3.2 2structura de programacin en CUDA
2. Requerimientos
Los reuisitos para desarrollar en CUDA C son los siguientes6
Un procesador !abilitado para CUDA en una tarjeta gr#ica -vidia
Un driver para la tarjeta -vidia
2l 4it de desarrollo de CUDA
Un compilador estndar de C(C&&
8
Libreras optimizadas
9at!.!, 3LA:, 11/
Cdigo C'U "
7'U integrado
Compilador CUDA C
nvcc
2nsamblador
;ndependiente de la
9uina <'/0=
Cdigo
de la C'U
Driver de
CUDA
'er#ilador
Depurador
Compilador
C estndar
7'U C'U
Captulo 3 Introduccin a la programacin en CUDA
'uede aduirir el driver " el 4it de desarrollo en la pgina >eb o#icial de -vidia cu"a
direccin es !ttp6((>>>.nvidia.com(cuda. All podr descargar el driver gen+rico, el 4it de
desarrollo donde se encuentra el compilador -.CC, las libreras " conjunto de recursos para
pro#undizar en la programacin con 7'Us CUDA.
'ara el compilador gen+rico puede utilizar 9icroso#t .isual C&& si se encuentra en
?indo>s, 7-U C&& <gcc= si es usted usuario de Linu%, " en caso de ue utilice un sistema
operativo en 9ac $: 0 deber tener instalada la versin ,@.A.B de C:no> LeopardD. 'or
Eltimo tendr ue instalar el 4it de desarrollo de Apple 0code para poder compilar en C&&.
'ara #acilitar las cosas
,
, en este libro se anima al lector a utilizar el entorno de
desarrollo multiplata#orma CodeLite para C(C&& ue permite la especi#icacin de diversos
compiladores segEn el tipo de cdigo #uente. -o obstante, si usted tiene su#icientes
conocimientos de programacin es libre de usar cualuier entorno de desarrollo, e incluso, si
es una avezado programador, no utilizar ninguno.
-o debe olvidar ue si su idea es aduirir una tarjeta -vidia para programar con los
conocimientos aduiridos en este libro, no deje de ec!ar un vistazo a la tabla 5., donde se
listan los modelos de 7'U -vidia con soporte para CUDA.

Nidia !eForce Nidia !eForce
"o#ile
Nidia $uadro Nidia $uadro
mo#ile
7e1orce 7/0 AF@
7e1orce 7/0 AG@
7e1orce 7/0 AB@
7e1orce 7/0 AH@ /i
7e1orce 7/0 AA@ /i
7e1orce 7/0 IG@
7e1orce 7/0 IB@
7e1orce 7/0 IHA
7e1orce 7/0 IH@
7e1orce 7/0 IH@
:2 7e1orce 7/:
IA@ 7e1orce 7/ II@
7e1orce 7/ I5@
7e1orce 7/ I8@
7e1orce 7/0 8FA
7e1orce 7/0 8GA
7e1orce 7/0 8G@
7e1orce 7/0 8BA
7e1orce 7/0 8H@
7e1orce 7/: 8A@
7e1orce 7/: 8I@
7e1orce 7/ AAA9
7e1orce 7/ AA@9
7e1orce 7/ AI@9
7e1orce 7/ A8A9
7e1orce 7/ A8@9
7e1orce 7/0 IG@9
7e1orce 7/0 IB@9
7e1orce 7/0 IH@9
7e1orce 7/ IIA9
7e1orce 7/ I5A9
7e1orce 7/ I8A9
7e1orce 7/ I8@9
7e1orce 7/ I,A9
7e1orce 7/0 8GA9
7e1orce 7/0 8G@9
7e1orce 7/0 8H@9
7e1orce 7/: 5H@9
7e1orce 7/: 5A@9
7e1orce 7/: 8H@9
7e1orce 7/: 8A@9
7e1orce 7/ 55A9
Juadro H@@@
Juadro A@@@
Juadro I@@@
Juadro 8@@@
Juadro H@@
Juadro 10 AG@@
Juadro 10 AH@@
Juadro 10 IG@@
Juadro 10 IB@@ 08
Juadro 10 IH@@
Juadro 10 5G@@
Juadro 10 5B@@
Juadro 10 ,G@@
Juadro 10 ,B@@
Juadro 10 AG@
Juadro 10 AB@
Juadro 10 5G@
Juadro 10 5B@
Juadro -.: IA@
Juadro -.: I8@
Juadro -.: 8FA
Juadro A@@@9 Juadro
10 5G@@9 Juadro 10
5B@@9 Juadro 10
5H@@9 Juadro 10
8G@@9 Juadro 10
8B@@9 Juadro 10
,G@@9 Juadro 10
,B@@9 Juadro 10
,H@@9 Juadro 10
GG@9 Juadro 10
BB@9 Juadro 10
AB@9 Juadro 10
5G@9 Juadro 10
5B@9 Juadro 10
5H@9 Juadro -.:
58@9 Juadro -.:
,H@9 Juadro -.:
,A@9 Juadro -.:
,I@9 Juadro -.:
,5A9 Juadro -.:
,5@9
, 2n el ap+ndice de este libro se inclu"e una seccin de con#iguracin del entorno de desarrollo
) Carlos *im+nez de 'arga 5
Captulo 3 Introduccin a la programacin en CUDA
7e1orce 7/ 8I@
7e1orce 7/ 88@
7e1orce 8,@(78,@
7e1orce FG@@ 708
7e1orce FG@@ 7/0&
7e1orce FG@@ 7/0
7e1orce FG@@ 7/
7e1orce FH@@ 7:$
7e1orce FH@@ 7/
7e1orce FA@@ 7/
7e1orce FI@@ 7/
7e1orce FI@@ m7'U
7e1orce F5@@ m7'U
7e1orce F,@@ m7'U
7e1orce GG@@ Ultra
7e1orce GG@@ 7/0
7e1orce GG@@ 7/:
7e1orce GG@@ 7/
7e1orce GG@@ 7:
7e1orce GH@@ 7/:
7e1orce GH@@ 7/
7e1orce GH@@ m7/
7e1orce GA@@ 7/
7e1orce GI@@ 7:
7e1orce G5@@ m7'U
7e1orce G8@@ m7'U
7e1orce G,@@ m7'U
7e1orce 7/ 55@9
7e1orce 7/ 58A9
7e1orce 7/ 58@9
7e1orce 5,@9
7e1orce 7/ 8I@9
7e1orce 7/ 85@9
7e1orce 7/ 88@9
7e1orce 78,@9
7e1orce 7/: ,H@9
7e1orce 7/: ,A@9
7e1orce 7/ ,5@9
7e1orce 7/ ,8@9
7e1orce 7,,@9
7e1orce 7,@A9
7e1orce 7,@59
7e1orce 7,@89
7e1orce 7,@@ 7e1orce
FG@@9 7/0 7e1orce
FG@@9 7/: 7e1orce
FG@@9 7/ 7e1orce
FG@@9 7: 7e1orce
FB@@9 7/: 7e1orce
FB@@9 7/ 7e1orce
FHA@9 7/ 7e1orce
FHA@9 7: 7e1orce
FH@@9 7/ 7e1orce
FH@@9 7: 7e1orce
FA@@9 7: 7e1orce
FA@@9 7 7e1orce
FI@@9 7 7e1orce
F5@@9 7: 7e1orce
F5@@9 7 7e1orce
F8@@9 7: 7e1orce
F,@@9 7 7e1orce
GG@@9 7/0 7e1orce
GG@@9 7/: 7e1orce
GB@@9 7/ 7e1orce
GH@@9 7/ 7e1orce
GH@@9 7: 7e1orce
GI@@9 7/ 7e1orce
GI@@9 7: 7e1orce
GI@@9 7 7e1orce
G8@@9 7
Juadro -.: 8F@
Juadro 'le% ,@@@
9odel ;.
Juadro 'le% ,@@@
9odel :I
Nidia %esla
/esla C8@A@(8@B@
/esla 98@A@(98@B@
/esla :8@A@
/esla :,@B@
/esla 9,@H@
/esla C,@H@
/esla CGB@
/esla DGB@
/esla :GB@
%a#la 3.1 Lista de 7'Us con capacidad para CUDA
I
Captulo 3 Introduccin a la programacin en CUDA
&ersion !'Us "odelo de tar(eta
,.@ 7G@ 7e1orce GG@@7/0(Ultra(7/:, /esla C(D(:GB@, 10I(AH@@, 5H@9
,.,
7GH, 7GI, 7FG,
7FH, 7FHb, 7FI,
7FIb, 7F8, 7F8b
7e1orce GI@@7:(7/, GH@@7/(7/:, GG@@7/(7/:,
FH@@7/(7:$, FG@@7/(7/0(708, 7/: 8A@, 7/ ,8@(5@, 10
I(AB@, 5(AG@, ,B(,G(5B@@, IB@@%8, ,%%9, 58(5B@9, 5(A(BB@9,
,H(,B(8B(8G(5H(5B(5G@@9, -.:I8@(A@
,.8
7/8,G, 7/8,H,
7/8,A
7e1orce 8,@, 7/ 88@(I@, 105G@ L', ,G@@9, 5B@(5G@9, -.:
8(5,@@9
,.5 7/8@@, 7/8@@b
7e1orce 7/0 8H@, 7/0 8BA, 7/0 8G@, 7/0 8GA, 7/0 8FA,
/esla C(9,@H@, :,@B@, Juadro C0, 10 5(I(AG@@
8.@ 71,@@, 71,,@
7e1orce <71,@@= 7/0 IHA, 7/0 IB@, 7/0 IG@, /esla C8@A@,
C8@B@, :(98@A@(B@, Juadro 'le% B@@@, 7e1orce <71,,@=
7/0AB@, 7/0AG@, 7/0AF@
8.,
71,@G, 71,@H,
71,@I, 71,,I,
71,,H
7e1orce 7/ I8@, 7/ I5@, 7/ II@, 7/: IA@, 7/0 IH@, 7/0 AA@
/i, 7/0 AH@ /i, A@@9, Juadro H@@, 8@@@, I@@@, A@@@, H@@@
%a#la 3.2 /abla de capacidad de cmputo <versin de CUDA soportada= por c!ip "
modelo de tarjeta
3. Un primer programa en CUDA
Antes de comenzar a codi#icar el primer programa en CUDA, " si usted !a seguido
las especi#icaciones del ap+ndice, comprobar ue e#ectivamente el compilador ejecuta
correctamente el cdigo C&&. 'ara ello intente escribir en CodeLite o su ;D2 pre#erido el
siguiente #ragmento en C6
#include <stdio.h>
int main(int argc, char **argv)
{
printf("Hola mundo\n");
return ;
!
La simplicidad de este ejemplo estriba en el !ec!o de ue slo genera cdigo en el
lado del host
2
.
'asemos a!ora a realizar la primera llamada al kernel. De#iniremos un kernel como
el procedimiento en C, no recursivo " no anidado ue implementa el cdigo paralelizado en
CUDA. 'ara ello ser necesario identi#icar el procedimiento con la palabra clave
""glo#al""
Dic!o de otra #orma, el procedimiento ue implementa el kernel no puede devolver
8 Llamaremos a la C'U " su memoria como !ost " a la 7'U " su memoria como dispositivo
) Carlos *im+nez de 'arga A
Captulo 3 Introduccin a la programacin en CUDA
ningEn valor " debe estar antecedido por el cali#icador ""glo#al""
De esta #orma uedara una estructura de llamada al kernel como en el siguiente
ejemplo6
#include <stdio.h>
""glo#al"" void $ernel(void){
!
""glo#al"" void foo(void){
!
int main(int argc, char **argv){
$ernel <<<%,%>>>();
foo <<<%,%>>>();
printf("Hola mundo&n");
return ;
!
$bserve ue en primer lugar se !ace una llamada al kernel $ernel " posteriormente
se llama al 4ernel foo. $bviamente estas llamadas al estar vacas no realizarn ninguna
operacin en la 7'U, simplemente volvern sin realizar nada.
La palabra reservada ""glo#al"" indica al compilador nvcc ue genere cdigo
para la 7'U en vez de la C'U.
$tra consideracin a tener en cuenta son los ngulos para indicar parmetros ue
sern pasados al sistema en tiempo de ejecucin. 2stos parmetros no indican argumentos
ue sern pasados al cuerpo del procedimiento implementado en el kernel, sino ue
indicarn al sistema cmo lanzar el cdigo ue se ejecutar en el dispositivo. 2s posible
pasar parmetros al kernel especi#icndolos con par+ntesis, aunue esto se ver ms
adelante.
Juiz sea Etil para el lector realizar una llamada a una #uncin desde el kernel. 'ara
este propsito e%iste la palabra reservada ""device"" ue indicar al compilador de
CUDA ue genere cdigo e%clusivamente como una #uncin para ser llamada desde el
kernel o desde otra #uncin. De esta manera tendramos el siguiente ejemplo6
#include <stdio.h>
""device"" float f'(float ', float (){
return ' ) (;
!
""glo#al"" void $ernel(void){
funcion(%., *.);
!
int main(int argc, char **argv){
$ernel <<<%,%>>>();
printf("+lamada a funci,n desde $ernel\n");
return ;
!
H
Captulo 3 Introduccin a la programacin en CUDA
Donde la #uncin f' realiza la suma de dos parmetros de tipo float.
). Reserando memoria
$tro aspecto importante de CUDA es la reserva " la liberacin de memoria. 2stos
son aspectos cruciales en el momento de disear una aplicacin.
-ormalmente se reservar memoria para realizar alguna operacin en el dispositivo,
tales como devolver valores al host o pasar grandes estructuras de datos, tales como tablas o
matrices al dispositivo. 'ara llevar a cabo esto recurriremos a la #uncin reservada
cuda-alloc(), similar al malloc()de C " ue reserva memoria en una zona de
especial llamada Heap.
2l prototipo de las #unciones ue veremos a continuacin son las siguientes6
cuda.rror"t cuda-alloc (void** dev/tr,si0e"t si0e)
Donde el primer parmetro es un puntero a puntero donde ueremos almacenar los
datos reservados en la memoria de la 7'U, " el segundo es el tamao de la reserva en b"tes.
cuda.rror"t cuda-emcp( (void* dst, const void *src, si0e"t count,
enum cuda-emcp(1ind $ind)
2l primer parmetro es un puntero a la zona de memoria de destino de la copiaK el
segundo la zona #uente de copiaK el tercero, la cuenta en b"tes de la copia, " por Eltimo, el
cuarto, ue especi#ica si el movimiento de b"tes es desde el !ost al dispositivo o al contrario.
Figura 3.3 $rden de accin de las primitivas de reserva de memoria " copia
'ara comprender los conceptos sobre reserva de memoria, considere el siguiente
#ragmento de cdigo6
#include <stdio.h>
#include <iostream>
22 3nclu(e utilidades de 4567
#include <cutil.h>
) Carlos *im+nez de 'arga B
*+,%
*+,%
Dispositio
Dispositio
cuda9alloc
cuda9emcp"
malloc
Captulo 3 Introduccin a la programacin en CUDA
""glo#al"" void #usca4adena(char *cadena, int longitud, char caracter,
#ool *encontrado){
int i 8 ;
9hile ((cadena:i; <8 caracter) == i < longitud)
i));
*encontrado 8 (i <8 longitud) > true ? false;
!
int main(int argc, char **argv){

char H@ABcad:CD; 8 {"EolverFn las oscuras golondrinas"!;
#ool H@ABencontrado;
char *G/5cad;
#ool *G/5encontrado;
4567"A7H."47++(cuda-alloc((void**)=G/5encontrado,si0eof(#ool)));
4567"A7H."47++(cuda-alloc((void**)=G/5cad, si0eof(char) * C*));
4567"A7H."47++(cuda-emcp((G/5cad,
H@ABcad,si0eof(char)*C*,
cuda-emcp(HostBo6evice));
#usca4adena<<<%,%>>>(G/5cad, C*, IiI, G/5encontrado);
4567"A7H."47++(cuda-emcp((=H@ABencontrado,
G/5encontrado, si0eof(#ool),
cuda-emcp(6eviceBoHost));
std??cout << "4arFcter encontrado? " << ((H@ABencontrado) > "si" ?
"no") << std??endl;
cudaHree(G/5encontrado);
cudaHree(G/5cad);
return ;
!
Lste es un peueo programa de ejemplo ue realiza la bEsueda de un carcter en
una cadena. Aunue la dimensin del problema es nimia para las capacidades de la 7'U, se
supone ue ilustra adecuadamente los propsitos del ejemplo.
Como puede observar el lector, las reservas de memoria en el lado del !ost se
realizan de la misma #orma ue la declaracin de variables en programacin imperativa
convencional de C. :in embargo, para las variables como G/5encontrado, ue se
representan como un puntero, es necesario reservar memoria en la zona del dispositivo
mediante la primitiva cuda-alloc ue aduirir tantos b"tes en la memoria de la 7'U
como le indiuemos en el segundo parmetro. -ote ue todas las variables ue son de
intercomunicacin entre el !ost " el dispositivo deben ser reservadas de esta manera.
Una vez aduirida la memoria en la zona de la 7'U, se precisa gestionar las
transacciones, "a sea entre el !ost " el dispositivo o a la inversa. 'ara llevar a cabo este
cometido tendremos ue utilizar la primtiva cuda-emcp( proporcionada por el
compilador " cu"o cometido es realizar la copia de b"tes entre el !ost " el dispositivo. /al es
el caso de la primera llamada del programa de ejemplo, donde se realiza una copia entre los
G
Captulo 3 Introduccin a la programacin en CUDA
datos de la cadena de te%to creada en el !ost <H@ABcad= " la zona de memoria con #ormato
de cadena en la 7'U <G/5cad=.
2l detalle ms caracterstico de esta llamada es el cuarto parmetro. Au se indica el
sentido de la copia, denotado como cuda-emcp(Bo6evice para indicar al !ost ue
debe trans#erir la in#ormacin a la memoria de la tarjeta de vdeo.
Una vez preparados los datos, "a es posible llamar al kernel con los argumentos
de#inidos anteriormente. 2n el caso de ue la #uncin del kernel encuentre el carcter
buscado, devolver el valor true en la variable reservada previamente en la 7'U para
almacenar el resultado. 2n resumen, una vez #inalizado el procesamiento en el dispositivo,
se procede a copiar la variable G/5encontrado en H@ABencontrado mediante la
llamada cuda-emcp( con el cuarto parmetro igual a cuda-emcp(6eviceBoHost
ue indicar ue las trans#erencia del resultado se realizar desde la 7'U al !ost.
:i la compilacin " ejecucin !an ido correctamente el programa deber visualizar6
4araJter encontrado? si
'or Eltimo, #alta aEn la parte ms importante de la gestin de la memoria, ue es su
liberacin " devolucin al sistema. De acuerdo a un orden de correcta gestin de memoria,
se precisar de la primitiva del compilador cudaHree. 2sta #uncin libera la memoria
previamente reservada con la llamada a cuda-alloc. 1jese el lector ue la poltica
seguida por el compilador de CUDA es id+ntica ue la utilizada en el estndar C.
A lo largo del programa se !a utilizado la llamada a la macro 4567"A7H."47++.
2sta macro proporciona in#ormacin " parada de la ejecucin cuando se detecta un valor
errneo en la llamada o el retorno de cualuier #uncin CUDA.
Memos visto un ejemplo clave ue ilustra el manejo de punteros " memoria, pero
desa#ortunadamente, el compilador no puede proteger al programador de un error de gestin
de los punteros en tiempo real. 'or ello, se resumen au los posibles casos " restricciones
en el uso de punteros en CUDA6
:e pueden pasar punteros reservados con cuda-alloc a #unciones ue se
ejecuten en el dispositivo
:e pueden usar punteros reservados con cuda-alloc para leer o escribir en
memoria desde el cdigo ue se ejecuta en la 7'U
:e pueden pasar punteros reservados con cuda-alloc a #unciones ue se ejecutan
en el lado del !ost
-o se pueden usar punteros reservados con cuda-alloc para leer o escribir en
memoria desde el cdigo ue se ejecuta en el !ost
) Carlos *im+nez de 'arga F
Captulo 3 Introduccin a la programacin en CUDA
,@
Importante- 9over datos desde memoria del host a memoria de la 7'U
consume tiempo. La causa es cuello de botella del anc!o de banda del
bus 'C; e%press.
Captulo 4 Programacin paralela
4
Programacin paralela
1. Un sencillo ejemplo
Comenzaremos esta introduccin a la programacin paralela exponiendo un breve
ejemplo de programa para calcular el algoritmo SAXPY (Single-precision real Alpha X Plus
Y) mu! utilizado en "lgebra lineal cu!a #rmula viene dada como$
y = x + y
%magine dos secuencias de n&meros enteros x e y almacenadas en dos arra!s' (a
idea )ue pretendemos es multiplicar el primer vector de enteros por un escalar ! sumarle
los componentes del segundo vector y, #inalmente el resultado se almacenar" en el arra! z.
*r"#icamente nuestro propsito es el siguiente$
Figura 4.1 +jemplo del algoritmo SAXPY

Antes de desarrollar el ejemplo en el respectivo cdigo paralelo considere el lector
el siguiente ejemplo de algoritmo en #orma secuencial para SAXPY'
, Carlos -im.nez de Parga /
0 0 0 0 0 0 0 0 0
x x x x x x x x x
1 1 1 1 1 1 1 1 1
X
Y
Z
' ' '
' ' '
' ' '
Captulo 4 Programacin paralela
#include <stdio.h>
#include <iostream>
#include <cutil.h>
#define N 10
void saxpySerie(int *x, int *y, int alfa, int* !
"
for (int i#0$ i<N$ i%%!
&i' # alfa * x&i' % y&i'$
(
int main(int ar)c, char **ar)v!
"
const int alfa # *$
int +,-x&N', +,-y&N', &N'$
srand (time(NULL!!$
for (int i#0$ i<N$ i%%!
"
+,-x&i' # rand(!.10$
+,-y&i' # rand(!.10$
(
saxpySerie(+,-x, +,-y, alfa, !$
std//cout << 01esultado procesamiento serie/0 << std//endl$
for (int i#0$ i<N$ i%%!
std//cout << alfa << 0 * 0 <<
+,-x&i' << 0 % 0 << +,-y&i' <<
0 # 0 << &i' << std//endl$
return 0$
(
2bviamente este cdigo es &nicamente llevado a cabo por una sola CP3 en #orma
secuencial' Si se #ija en el bucle de saxpySerie observar" )ue la misma CP3 itera 4
veces sobre la misma operacin en los arra!s' +sto )uedar5a ilustrado de #orma desenrollada
como$
z678 9 al#a : x678 1 !678
z6/8 9 al#a : x6/8 1 !6/8
z6;8 9 al#a : x6;8 1 !6;8
z6<8 9 al#a : x6<8 1 !6<8
z6=8 9 al#a : x6=8 1 !6=8
z6>8 9 al#a : x6>8 1 !6>8
z6?8 9 al#a : x6?8 1 !6?8
z6@8 9 al#a : x6@8 1 !6@8
z6A8 9 al#a : x6A8 1 !6A8
z6B8 9 al#a : x6B8 1 !6B8
;
Captulo 4 Programacin paralela
C5jese cmo el bucle se repite id.nticamente para la misma operacin tan slo
cambia el 5ndice del arra!' Aprovechando este modelo se podr5a hacer una adaptacin a la
versin con varios microprocesadores' As5 de .sta #orma si tuvi.ramos dos CP3 el cdigo
anterior )uedar5a como$
void saxpy+,-1(int *x, int *y, int alfa, int* !
"
for (int i#0$ i<N$ i%#*!
&i' # alfa * x&i' % y&i'$
D
void saxpy+,-*(int *x, int *y, int alfa, int* !
"
for (int i#1$ i<N$ i%#*!
&i' # alfa * x&i' % y&i'$
D
2bviamente esta aproximacin no es ptima pues replicar el cdigo para cada CP3
re)uerir5a una gran in#raestructura ! una razonable cantidad de espacio en memoria'
Consecuentemente esta aproximacin no es del todo acertada'
2. Algoritmo SAXPY en GPU
Eealicemos ahora la misma operacin pero de una manera m"s e#iciente ! )ue
aproveche los recursos multin&cleo de la *P3 C3FA' +l cdigo )ue veremos a
continuacin es mu! similar al anterior en ciertos aspectos aun)ue tanto el kernel como la
#uncin main(!le pueden ser #amiliares si entendi correctamente el cap5tulo <'
+mpecemos exponiendo el programa principal$
#include <stdio.h>
#include <iostream>
#include <cutil.h>
#define N 10
int main(int ar)c, char **ar)v!
"
const int alfa # *$
int +,-x&N', +,-y&N', &N'$
int *2,-x, *2,-y$
srand (time(NULL!!$
for (int i#0$ i<N$ i%%!
"
+,-x&i' # rand(!.10$
+,-y&i' # rand(!.10$
(
, Carlos -im.nez de Parga <
CPU 1
CPU 1
CPU 2
CPU 2
Captulo 4 Programacin paralela
+-345S4675+488(cuda9alloc(:2,-x, sieof(int! * N!!$
+-345S4675+488(cuda9alloc(:2,-y, sieof(int! * N!!$
+-345S4675+488(cuda9emcpy(2,-x, +,-x,
sieof(int! * N, cuda9emcpy;ost<o3evice!!$
+-345S4675+488(cuda9emcpy(2,-y, +,-y,
sieof(int! * N, cuda9emcpy;ost<o3evice!!$
saxpy,aralelo<<<1,N>>>(2,-x,2,-y, alfa!$
+-345S4675+488(cuda9emcpy(, 2,-y,
sieof(int! * N, cuda9emcpy3evice<o;ost!!$
std//cout << 01esultado procesamiento paralelo/0 << std//endl$
for (int i#0$ i<N$ i%%!
std//cout << alfa <<
0 * 0 << +,-x&i' << 0 % 0 <<
+,-y&i' << 0 # 0 << &i' << std//endl$
cuda6ree(2,-x!$
cuda6ree(2,-y!$
return 0$
(
Al inicio del programa se reservan tres arra!s en la memoria del host )ue son CP3x
CP3! ! z. +l primer arra! reserva memoria para albergar los componentes del vector x el
segundo almacena el vector y ! por el &ltimo reserva memoria para devolver los resultados'
A continuacin creamos dos punteros$ *2,-x ! *2,-y donde se tendr" una re#erencia a
la memoria creada en el dispositivo' Gabr" notado el lector la llamada a la #uncin$
srand(time(N-88!!

cu!o cometido es generar un nuevo valor de semilla para la generacin de n&meros
aleatorios' +n este caso generaremos valores al azar entre 7 ! 4 H /I aun)ue para simpli#icar
el ejemplo se ha pre#erido optar por un n&mero pe)ueJo en este caso el valor /7'
Fespu.s de proceder a la inicializacin de los valores x e y llegamos a la parte de
reserva de memoria en el lado de la *P3' +n este caso se llama a la #uncin cuda9alloc
con los punteros 2,-x ! 2,-y )ue ser"n los responsables de mantener re#erencias a la
memoria ad)uirida en el dispositivo' Como )ueremos reservar 4 veces tantos b!tes como
ocupe un entero debemos multiplicar 4 por el tamaJo en b!tes devuelto por la #uncin C
sieof(!' Posteriormente procederemos a volcar la memoria con los componentes
aleatorios de los vectores x e y del lado del host a la zona del dispositivo' Para ello haremos
una llamada a cuda9emcpy pasando un puntero al arra! en el dispositivo como destino de
copia ! otro puntero al arra! en el host como #uente de inicio de la copia' Por &ltimo se
indica )ue el sentido de la copia$ cuda9emcpy;ost<o3evice'
Ahora llegamos a la parte clave del programa$ la llamada al kernel'
=
Captulo 4 Programacin paralela
Kodas las llamadas al kernel tiene el siguiente patrn$
funcin!ernel"""#lo$ues% t&rea's((()par*metros)
Ahora introduciremos dos nuevas palabras a la terminolog5a C3FA$ el threa ! los
!lo"ue#' (a divisin de la lgica del paralelismo en C3FA implica el concepto de threa
)ue es parecida a la idea de proceso ligero creado por el sistema operativo ! puesto a
disposicin del programador de sistemas' +l concepto de threa a)u5 descrito se re#iere a la
unidad b"sica de procesamiento paralelo' +stos threads son agrupados en blo)ues )ue son
procesados por los n&cleos' Por lo tanto podemos lanzar un kernel con hasta ?>'><> blo)ues
como m"ximo por dimensin donde el m"ximo de threads ejecut"ndose en cada blo)ue es
de >/;'
Por consiguiente en la llamada$

saxpy,aralelo<<<1,N>>>(2,-x,2,-y, alfa!$
Se lanzar"n un total de /7 threads en paralelo' (a parte de implementacin del kernel
es la siguiente$
55)lo=al55 void saxpy,aralelo(int *x, int *y, int alfa!
"
int i # thread>dx.x$
if (i < N!
y&i' # alfa * x&i' % y&i'$
(
Gabr" observado una nueva palabra reservada dentro del lenguaje C3FA' Lsta es
threadIdx.x cu!a #uncin es devolver el identi#icador del thread paralelo dentro del blo)ue
en cuestin donde el identi#icador puede variar entre 7 ! B en este ejemplo'

Pero considere el lector )ue 4 es igual a = esta vez' Kendr5amos la siguiente
ejecucin en paralelo$

, Carlos -im.nez de Parga >
55)lo=al55 void saxpy,aralelo(int *x, int *y, int alfa!
"
int i # 0$
if (i < N!
y&i' # alfa * x&i' % y&i'$
(
Khread
7
Captulo 4 Programacin paralela
+stos cuatro threads se ejecutar"n en paralelo ! acceder"n a una parte distinta
de los datos tal como se muestra en la #igura =';'
Figura 4.2 +jecucin paralela de threads
?
55)lo=al55 void saxpy,aralelo(int *x, int *y, int alfa!
"
int i # 1$
if (i < N!
y&i' # alfa * x&i' % y&i'$
(
Khread
/
55)lo=al55 void saxpy,aralelo(int *x, int *y, int alfa!
"
int i # *$
if (i < N!
y&i' # alfa * x&i' % y&i'$
(
Khread
;
55)lo=al55 void saxpy,aralelo(int *x, int *y, int alfa!
"
int i # ?$
if (i < N!
y&i' # alfa * x&i' % y&i'$
(
Khread
<
Khread
7
Khread
/
Khread
;
Khread
<
0
;
;
;
x
1
x
!
!
/
/
/
x
1
x
!
!
7
7
7
x
1
x
!
!
<
<
<
x
1
x
!
!
0 0 0
Captulo 4 Programacin paralela
Aun)ue tambi.n ser5a posible realizar la misma operacin de la siguiente manera$
55)lo=al55 void saxpy,aralelo(int *x, int *y, int alfa!
"
int i # =loc@>dx.x$
if (i < N!
y&i' # alfa * x&i' % y&i'$
(
Fonde blocM%dx'x devolver" el identi#icador del blo)ue lanzado en paralelo de la
misma #orma con )ue lanzamos anteriormente los threads' Por tanto la llamada al kernel se
realizar" como sigue$
saxpy,aralelo<<<N,1>>>(2,-x, 2,-y, alfa!$
Con el primer par"metro entre "ngulos indicando el n&mero de blo)ues a lanzar en
paralelo'
Cabe preguntarse por )u. utilizamos la salvaguarda if (i < N!dentro dentro del
cuerpo del procedimiento del kernel. (a respuesta a esta pregunta es simple' %magine )ue se
hubiera realizado la siguiente llamada$
saxpy,aralelo<<<100,1>>>(2,-x, 2,-y, alfa!$
Si no se hubiera utilizado la salvaguarda se hubiera accedido a posiciones ilegales de
la memoria al lanzar el kernel y dejando posiblemente la computadora blo)ueada'
Por &ltimo introduciremos un nuevo vocablo a la terminolog5a C3FA ! tambi.n
mu! utilizado en computacin paralelal$ el gri' Podemos denominar un gri como un grupo
de blo)ues paralelos )ue realizan una tarea determinada' +n este ejemplo )ue se ha mostrado
el gri ha sido de una sola dimensin'
, Carlos -im.nez de Parga @
Captulo 4 Programacin paralela
+. Suma 'e matrices
Ahora veremos otro ejemplo de utilizacin del kernel en dos dimensiones en la )ue
se utilizar"n nuevas variables del lenguaje C3FA C para identi#icar las #ilas ! las columnas
tanto de blo)ues como de threads' Para ilustrar estas nuevas variables reservadas
utilizaremos como ejemplo el algoritmo de la suma de matrices en el a)u5 exponemos su
expresin$
+sta estructura matem"tica es idnea para la programacin paralela seg&n la #iloso#5a
de C3FA seg&n veremos a continuacin'
Antes de explicar el cdigo #uente veamos un nuevo tipo de datos$
dim? 2rid(3>9, 3>9!
+l tipo impl5cito de C3FA C dim? no es un tipo C est"ndar ! permite crear una
tupla tridimensional' Se estar" preguntando por)u. utilizaremos una estructura de tres
dimensiones cuando una suma de matrices es siempre en dos dimensiones' Pues bien la
realidad es )ue aun)ue C3FA soporte el tipo interno dim? actualmente no est"
implementada la posibilidad de crear estructuras de tres dimensiones por lo )ue el
compilador de C3FA siempre esperar" )ue una variable de este tipo sea siempre igual a /
en su &ltimo par"metro es decir se considera )ue la &ltima dimensin e)uivaldr"
impl5citamente a /'
Considere el siguiente #ragmento de cdigo de la #uncin principal$
#include <stdio.h>
#include <iostream>
#include <cutil.h>
#define N 10
#define 9 10
#define <hreads A
int main(int ar)c, char **ar)v!
"
int +,-x&N'&9', +,-y&N'&9', +,-&N'&9'$
int *2,-x, *2,-y, *2,-$
+-345S4675+488(cuda9alloc((void**!:2,-x, N*9*sieof(int!!!$
+-345S4675+488(cuda9alloc((void**!:2,-y, N*9*sieof(int!!!$
+-345S4675+488(cuda9alloc((void**!:2,-, N*9*sieof(int!!!$
A
(
x
//
x
/;
x
/<
x
/m
x
;/
x
;;
x
;<
x
;m
x
</
x
<;
x
<<
x
<m
x
n$
x
n%
x
n&
x
nm
)
+
(
y
//
y
/;
y
/<
y
/m
y
;/
y
;;
y
;<
y
;m
y
</
y
<;
y
<<
y
<m
y
n$
y
n%
y
n&
y
nm
)
=
(
x
//
+ y
//
x
/;
+ y
/;
x
/<
+ y
/<
x
/m
+ y
/m
x
;/
+ y
;/
x
;;
+ y
;;
x
;<
+ y
;<
x
;m
+ y
;m
x
</
+ y
</
x
<;
+ y
<;
x
<<
+ y
<<
x
<m
+ y
<m
x
n$
+ y
n$
x
n%
+ y
n%
x
n&
+ y
n&
x
nm
+ y
nm
)
Captulo 4 Programacin paralela
dim? dimBloCue(<hreads, <hreads!$
dim? dim2rid((int!ceil(float(N! D float(<hreads!!,
(int! ceil(float(9! D float(<hreads!!!$
Nuiz" le resultar" algo #amiliar las primeras l5neas del programa' Su intencin es
declarar tres arra!s bidimensionales en el lado del host para almacenar las matrices de
origen ! destino' As5 mismo se declaran tres variables puntero donde se reservar" la
memoria para las matrices en el dispositivo'
Ahora #5jese en la siguiente declararcin$
dim? dimBloCue(<hreads, <hreads!$
A)u5 estamos indicando al compilador de C3FA C )ue cree un blo)ue de = x =
threads inscritos dentro de los blo)ues del gri de#inido por las siguientes expresin$
<hreads utiliados <hreads no utiliados
Figura 4.+ +structura del grid
, Carlos -im.nez de Parga B
!lo"ue#X=
columna# matriz
n'meroethrea# por !lo"ue

!lo"ue#Y=
(ila# matriz
n'mero ethrea# por !lo"ue

Khread
(77O
Khread
(/7O
Khread
(;7O
Khread
(<7O
Khread
(7/O
Khread
(//O
Khread
(;/O
Khread
(</O
Khread
(7;O
Khread
(/;O
Khread
(;;O
Khread
(<;O
Khread
(7<O
Khread
(/<O
Khread
(;<O
Khread
(<<O
,lo$ue )-%-) ,lo$ue )1%-)
,lo$ue )2%-)
,lo$ue )-%1) ,lo$ue )1%1) ,lo$ue )2%1)
,lo$ue )-%2) ,lo$ue )1%2)
,lo$ue )2%2)
Captulo 4 Programacin paralela
en la llamada a$
dim? dim2rid((int!ceil(float(N! D float(<hreads!!,
(int!ceil(float(9! D float(<hreads!!!$
+n el siguiente #ragmento de cdigo realizamos la inicializacin de los arra!s
srand (time(NULL!!$
for (int i#0$ i<N$ i%%!
for(int E#0$ E<9$E%%!
"
+,-x&i'&E' # rand(!.10$
+,-y&i'&E' # rand(!.10$
(
+-345S4675+488(cuda9emcpy(2,-x, +,-x, N*9*sieof(int!,
cuda9emcpy;ost<o3evice!!$
+-345S4675+488(cuda9emcpy(2,-y, +,-y, N*9*sieof(int!,
cuda9emcpy;ost<o3evice!!$
con valores en el intervalo 7-B ! copiamos las matrices origen a las direcciones de
memoria apuntadas por los punteros reservados en el lado del dispositivo'
Previo a realizar la llamada al kernel considere la declaracin del mismo$
55)lo=al55 void suma9atrices(int *x, int *y, int *!
"
int i # =loc@>dx.x * =loc@3im.x % thread>dx.x$
int E # =loc@>dx.y * =loc@3im.y % thread>dx.y$
int indice # i % E * N$
if (i < N :: E < 9!
&indice' # x&indice' % y&indice'$
(
4os encontramos a)u5 con una nueva variable de C3FA impl5cita )ue nos indica la
dimensin del blo)ue' +sta variable son =loc@3im.x ! =loc@3im.y para las
columnas ! las #ilas de la matriz respectivamente' 3na vez localizadas las posiciones
absolutas a partir de las variables de posicionamiento relativo procedemos a obtener el valor
del desplazamiento en el arra! de origen ! destino por medio de la #rmula$
/7
e#plazamiento=x+ yn'meroecolumna# matriz
Captulo 4 Programacin paralela
Y utilizamos una salvaguarda para evitar )ue los threads no utilizados es decir los
threads sombreados en la #igura ='< violen posiciones de memoria del dispositivo no
permitidas'
Ya slo )ueda llamar al kernel con las dos variables declaradas con el nuevo tipo de
datos antes explicado$
suma9atrices<<<dim2rid, dimBloCue>>>(2,-x, 2,-y, 2,-!$
+-345S4675+488(cuda9emcpy(+,-, 2,-, N*9*sieof(int!,
cuda9emcpy3evice<o;ost!!$
for (int i#0$ i<N$ i%%!
"
for(int E#0$ E<9$ E%%!
std//cout <<0 2,-/ 0 << +,-x&i'&E' << 0 % 0 << +,-y&i'
&E' << 0 # 0 << +,-&i'&E' <<
0 +,-/ 0 << +,-x&i'&E' << 0 % 0 << +,-y&i'&E' << 0 # 0
<< +,-x&i'&E' % +,-y&i'&E' << std//endl$
std//cout << 0FFFFFFFFFFFFFFFFFFF 6ila/ 0 << i << std//endl$
(
cuda6ree(2,-x!$
cuda6ree(2,-y!$
cuda6ree(2,-!$
return 0$
(
Como podr" apreciar se llamar" al kernel indicando al sistema las dimensiones del
gri ! de los blo)ues' Al #inalizar el procedimiento paralelo en la *P3 copiamos el
resultado devuelto en el puntero 2,- a la variable bididemsional +,- ! procedemos a
imprimir las matrices con los resultados calculados tanto por medio de la *P3 como de la
CP3' Por &ltimo no debemos olvidar liberar la memoria reservada en el dispositivo'
, Carlos -im.nez de Parga //
Captulo 4 Programacin paralela
4. Sincroni.acin 'e t&rea's / memoria comparti'a
+ntraremos ahora a explicar una nueva #orma de programacin paralela en C3FA
)ue sigue el paradigma algor5tmico )*i+ie y ,encer-#. por medio del uso de un nuevo tipo
de memoria )ue incrementa la e#iciencia ! el rendimiento' +ste nuevo tipo de memoria lo
llamaremos memoria compartia
$
)ue junto a las palabras reservadas de C3FA C
55device55 ! 55)lo=al55 denotar" un nuevo tipo de palabra clave )ue de#iniremos
como 55shared55 en ingl.s' +ste tipo de variable crea una copia de la variable por cada
blo)ue )ue se lanza en la *P3' Cada thread en ese blo)ue comparte dicha memoria pero los
threads de cada blo)ue no pueden acceder o modi#icar la copia de la variable compartida
declarada en otros blo)ues' (a memoria compartida reside #5sicamente en la *P3 en
contraposicin a la memoria FEAP de la tarjeta' +n consecuencia la latencia de acceso a
memoria compartida tiende a ser m"s baja )ue a los t5picos b&#eres' Febido a este nuevo
modelo de memoria introducido en la programacin C3FA ser" necesario nuevas t.cnicas
! mecanismos para la sincronizacin entre threads'
Qeamos un ejemplo sencillo )ue ilustra este caso$
4.1 01to'o 'e integracin 'el trapecio
(a regla del trapecio es un m.todo de integracin num.rica mu! utilizada en
matem"ticas para calcular aproximadamente el valor de la integral de#inida
(a idea consiste en aproximar el valor de la integral de (/x0 por el de la #uncin lineal
)ue pasa a trav.s de los puntos /a,(a/a00 ! /!,(/!00. Por lo tanto la integral de la #uncin (/x0
es igual al "rea del trapecio bajo la gr"#ica de la #uncin lineal$
Figura 4.4 (a #uncin curvil5nea (/x0 es aproximada por la #uncin lineal
/ Shared memor! en terminolog5a C3FA
/;

a
!
( (x)x
(/x0
Captulo 4 Programacin paralela
! para calcularla se sigue la siguiente #rmula$
donde el error se de#ine como$
Siendo R un n&mero comprendido en el intervalo 6ab8 ! (
/%0
la derivada segunda de
(/x0.
4.2 2egla 'el trapecio compuesta
Sas"ndonos en la #ormula anterior aplicaremos una nueva t.cnica )ue consiste en
aproximar una integral de#inida utilizando n veces la regla del trapecios' +n esta #ormulacin
se supone )ue (/x0 es continua ! positiva en el intervalo 6ab8' Fe tal modo )ue la integral
de#inida
representa el "rea de la regin delimitada por la gr"#ica de (/x0 ! el eje x desde x9a hasta
x9b' Primero se divide el intervalo 6ab8 en n subintervalos cada uno de ancho
Tx 9 (b H aO U n como puede verse en la #igura ='>'
Figura 4.3 %ntegracin aproximada por subintervalos e)uidistantes
Fespu.s de realizar todo el proceso matem"tico se llega a la siguiente #rmula$
, Carlos -im.nez de Parga /<

a
!
( (x)x(!a)
( (a)+ ( (!)
;
(!a)
<
/;
(
(;)
()

a
!
( (x)x
(/x0
Captulo 4 Programacin paralela
Fonde h=
(!a)
n
! n es el n&mero de divisiones'
Cinalmente la expresin se puede simpli#icar como$
4.+ 4mplementacin en 5U6A con memoria comparti'a
Qeamos la #orma de implementar la integral por la regla del trapecio utilizando la
memoria compartida (#hare memoryO ! la sincronizacin de threads' Considere el siguiente
#ragmento del cdigo del kernel$
#include <stdio.h>
#include <math.h>
#include <iostream>
#include <cutil.h>
DD NGmero de intervalos
const int N # H0000$
const int num<hreads # *IJ$
const int =loCues,or2rid # min(?*, (N % num<hreads F 1! D num<hreads!$
55device55 float funcion5)pu(float x!
"
return sin(1Dx!*poK(x,?!D(x % 1!*(x%*!$
(
float funcion5cpu(float x!
"
return sin(1Dx!*poK(x,?!D(x%1!*(x%*!$
(
55)lo=al55 void trapecios(float a, float =, float h, float* resultado!
"
55shared55 float parcial&num<hreads'$
int iteracion # thread>dx.x % =loc@>dx.x* =loc@3im.x$
float temp # 0$
Khile ( iteracion < N !
"
if (iteracion L# 0!
temp %# funcion5)pu(a % h * iteracion!$
/=

a
!
( (x) x
h
;
[ ( (a)+ ;# (a+ h)+ ;# ( a+ ;h)+ '''+ ( (!)]

a
!
( ( x)x
(!a)
n
(
( (a)+ ( (!)
;
+

k=/
n/
(
(
a+ k
!a
n
))
Captulo 4 Programacin paralela
iteracion %# =loc@3im.x * )rid3im.x$
(
parcial&thread>dx.x' # temp$ DD 4lmacena los resultados parciales
Krataremos de aproximar$
Como podr" observar el lector utilizaremos una variable de memoria compartida para
cada blo)ue con un tamaJo de ;>? threads
;
donde almacenaremos las sumas parciales de
55shared55 float parcial&num<hreads'$
Fonde cada thread procesa un intervalo del algoritmo de trapecios iterando hasta 4'

Figura 4.7 Suma de los subintervalos
; Eecuerde )ue el m"ximo de blo)ues )ue se pueden lanzar en cada dimensin del grid es de ?>><> ! el m"ximo de
threads por blo)ue es de >/;
, Carlos -im.nez de Parga />

k=/
n/
(
(
a+ k
!a
n
)

k=/
n/
(
(
a+ k
!a
n
)

k=;
n/
(
(
a+ k
!a
n
)

k=;>>
n/
(
(
a+ k
!a
n
)

k=@B<?
n/
(
(
a+ k
!a
n
)

k=@B<@
n/
(
(
a+ k
!a
n
)

k=A/B/
n/
(
(
a+ k
!a
n
)

/'>
;'@A
( (x)x
( (x)=
#en(
/
x
)x
<
(x+ ;)
(x+ /)
Slo)ue 7
Slo)ue 7
Khread /
Khread ;
Khread ;>>
'
'
Slo)ue </
Slo)ue </
Khread /
Khread ;
Khread ;>>
'
'
'
'
Pemoria
compartida
Pemoria
compartida
G
r
i
'
1
1
1
1
1
1
Captulo 4 Programacin paralela
donde M representa la variable iteraciMn'
as5 tendremos un total de A/B/ threads ejecut"ndose simult"neamente para calcular
las sumas parciales e iterando con el salto de#inido por$
iteracion %# =loc@3im.x * )rid3im.x$
A)u5 se nos presenta una nueva variable impl5cita de#inida por el compilador C3FA
C$ )rid3im )ue con sus propiedades )rid3im.x ! )rid3im.y nos proporciona la
dimensin del grid en blo)ues )ue en este caso es <; puesto )ue &nicamente utilizamos la
dimensin x' Fe esta #orma el salto en el incremento anterior ser" de un total de A/B;
iteraciones )ue sumar"n todos los subintervalos'
Nuiz" se habr" #ijado por )u. no utilizamos la iteracin 7' +sto lo haremos as5 por la
sencilla razn de no tener )ue sumar un intervalo incorrecto al sumatorio'
Cinalmente al salir del bucle se utilizar" la memoria compartida para almacenar cada
resultado accediendo con el identi#icador del thread en cada blo)ue'
parcial&thread>dx.x' # temp$
3na vez )ue la primera #ase ha calculado los subintervalos ! almacenado las sumas
parciales procedemos a agrupar los resultados de cada arra! )ue representa la variable
compartida' Pero previamente a realizar esta operacin tenemos )ue esperar a )ue todos los
threads terminen la #ase de c"lculo de los subintervalos puesto )ue esto es una operacin
potencialmente peligrosa' 4ecesitamos un m.todo )ue garantice )ue todas las escrituras en
el arra! parcial&' se completen antes de )ue cual)uier otra operacin de
lecturaUescritura se realice en este b&#er' Por suerte tenemos la siguiente primitiva de
sincronizacin en C3FA C$
55syncthreads(!
Con esta primitiva nos aseguramos )ue cuando el primer thread ejecute la primera
intruccin despu.s de V5syncthreads(!, todos los otros threads del blo)ue han
llegado tambi.n a 55syncthreads(!'
Ya hemos conseguido )ue nuestro arra! se complete con los valores adecuados
ahora podemos proceder a sumarlos' Fenominaremos esta simple operacin de suma de
totales de un arra! de entrada en un arra! m"s pe)ueJo con los resultados #inales como
reuccin' (a reduccin es una t.cnica mu! utilizada a menudo en programacin paralela'
(a idea )ue aplicaremos consiste en particionar el arra! de memoria compartida en
dos partes iguales para cada thread del blo)ue' 3na vez )ue el thread entra en el bucle 1hile
procede de manera similar dividiendo el arra! en dos partes iguales (siempre ! cuando el
valor de i permita acceder al thread actualO ! sumando la posicin )ue representa el thread
en el arra! con su semejante en la otra parte. Como vemos existe un segundo
55syncthreads(! )ue permite )ue todos los threads anteriores accedan otra vez al
arra! cuando ha!an terminado su parte sin in#ringir las lecturasUescrituras con otros threads
posteriores' +ste procedimiento se repite log
%
n&mero de threads por blo)ue veces' (a #igura
/?
Captulo 4 Programacin paralela
='@ ilustra este algoritmo de reduccin general$
<hreads a los Cue se les permite acceso
Figura 4.8 Proceso de reduccin
A continuacin se expone el cdigo )ue implementa el algoritmo de reduccin$
int i # =loc@3im.x D *$
Khile ( iL#0 ! DD 6ase de reducciMn
"
if (thread>dx.x < i!
parcial&thread>dx.x' %# parcial&thread>dx.x % i'$
55syncthreads(!$
i D# *$
(
Por &ltimo se procede a devolver el valor del resultado de las sumas parciales del
arra! parcial&' en memoria global2
if (threadIdx.x ## 0!
resultado&blockIdx.x' # parcial&0'$
(
Se preguntar" por )u. el valor global se almacena para thread>dx.x ## 0.
+sto es as5 puesto )ue slo ha! un n&mero )ue necesita escribir en memoria global
solamente un &nico thread necesita realizar dicha operacin' +n verdad podr5a haber sido
cual)uier thread el )ue hubiera realizado este trabajo ! el programa #uncionar5a de manera
, Carlos -im.nez de Parga /@
; @ / = 7 < ; ?
; /7 < /7
Suponemos blocMFim'x 9 A
i 9 =
> ;7
;>
i 9 ;
i 9 /
i 9 7 6Cin8
i U9;
Captulo 4 Programacin paralela
exactamente igual pero esto crear5a una gran cantidad de tr"#ico en memoria innecesario
para almacenar el valor'
Ahora )ue hemos visto cmo se lanza el Mernel para el c"lculo de la integral
podemos #inalmente exponer el programa principal para el ejemplo de la regla del trapecio$
int main(int ar)c, char **ar)v!
"
const float a # 1.If$
const float = # *.NHf$
float h # (= F a! D N$
float *resultado5cpu$
float *resultado5)pu$
resultado5cpu # (float*!malloc(=loCues,or2rid * sieof(float!!$
+-345S4675+488(cuda9alloc(:resultado5)pu, =loCues,or2rid *
sieof(float!!!$
trapecios<<<=loCues,or2rid,num<hreads>>>(a, =, h, resultado5)pu!$
+l cdigo )ue se expone es #"cilmente entendible' Para )ue la explicacin no le
parezca un aburrimiento pasaremos a resumir brevemente su cometido$
+stablece los l5mites de integracin in#erior (/'>O ! superior (;'@AO como
constantes'
Eeserva memoria en el lado del host para el resultado devuelto por el kernel'
Eeserva memoria en el lado del dispositivo para almacenar las sumas
parciales devueltas por el kernel'
(lama al Mernel con un determinado n&mero de threads ! blo)ues para el
gri'
+n la seccin ='< se vi la inicializacin de las constantes en el encabezamiento del
programa' Para su claridad volvemos mostrarlas$
DD NGmero de intervalos
const int N # H0000$
const int num<hreads # *IJ$
const int =loCues,or2rid # min(?*, (N % num<hreads F 1! D num<hreads!$
Primero establecemos el n&mero de subintervalos a A7777 con un total de ;>?
threads por blo)ue' Nuiz" ahora se est. preguntando cmo calculamos en n&mero de
blo)ues por gri a partir de la #ormula expuesta puesto )ue merece la pena examinar este
valor' Qimos cmo para calcular la regla del trapecio se utiliza un proceso de reduccin para
/A
Captulo 4 Programacin paralela
calcular las sumas parciales' +l tamaJo de esta lista de sumas parciales deber5a ser adecuada
para la CP3 ! lo su#icientemente grande de manera )ue tengamos su#icientes blo)ues
ejecut"ndose para mantener la *P3 lo m"ximo ocupada' Para conseguir este e)uilibrio
hemos seleccionado un tamaJo de <; blo)ues aun)ue el rendimiento de esta ci#ra puede
variar dependiendo de la velocidad de la CP3 ! la *P3'
+n caso de )ue el valor de 4 sea mu! pe)ueJo ! los <; blo)ues con ;>? threads sea
demasiado grande para el cmputo utilizaremos las #rmula matem"tica general )ue
devuelve siempre el m&ltiplo m"s pe)ueJo de num<hreads )ue es m"s grande o igual a
4$
Y por tanto el n&mero de blo)ues )ue ejecutamos ser" el menor entre <; o el valor de
la #rmula anterior$
const int =loCues,or2rid # min(?*, (N % num<hreads F 1! D num<hreads!$
Fespu.s de llamar al Mernel debemos de copiar los datos devueltos por el
procesamiento de la *P3 mediante la llamada a cuda9emcpy/
+-345S4675+488(cuda9emcpy(resultado5cpu, resultado5)pu, =loCues,or2rid *
sieof(float!, cuda9emcpy3evice<o;ost!!$
Ya slo #alta sumar las sumas parciales devueltas en el arra! resultado5cpu
teniendo claro de antemano )ue la longitud de los datos es su#icientemente pe)ueJa para la
CP3 ! )ue no va a a#ectar al rendimiento$
float suma5parciales # (funcion5cpu(a! % funcion5cpu(=!! D *.0f$
for (int i # 0$ i < =loCues,or2rid$ i%%!
suma5parciales %# resultado5cpu&i'$
suma5parciales *# h$
std//cout << 01esultado de inte)ral con 2,-/ 0 << suma5parciales <<
std//endl$
Puesto )ue resultado5cpu&' contiene nos #alta sumarle
! por &ltimo multiplicar el valor por h'
A continuacin aJadimos el #ragmento de cdigo )ue realiza la misma operacin de
trapecios en serie sobre la CP3$
, Carlos -im.nez de Parga /B
(3+ (num4hrea#/))
num4hrea#

k=/
n/
(
(
a+ k
!a
n
)
( (a)+ ( (!)
;
Captulo 4 Programacin paralela
suma5parciales # (funcion5cpu(a! % funcion5cpu(=!! D *.0f$

for(int i#1$ i<N$ i%%!
suma5parciales %# funcion5cpu(a % i*h!$
suma5parciales *# h$
std//cout << 01esultado de inte)ral con +,-/ 0 << suma5parciales <<
std//endl$
cuda6ree(resultado5)pu!$
free(resultado5cpu!$
return 0$
(
Como podr" claramente comprobar el cdigo para el lado del host es mucho m"s
simple )ue su homlogo para la *P3' (a di#erencia estriba en el rendimiento pues calcular
los A7777 subintervalos con la CP3 es mucho m"s lento )ue paralelizado en la *P3' +n el
cap5tulo A veremos m"s detalladamente los aspectos de medida del rendimiento en
programacin paralela versus serie'
Cinalmente ! para ma!or claridad aJadimos el cdigo #uente completo para el
algoritmo de c"lculo de una integral por la regla del trapecio$
#include <stdio.h>
#include <math.h>
#include <iostream>
#include <cutil.h>
DD NGmero de intervalos
const int N # H0000$
const int num<hreads # *IJ$
const int =loCues,or2rid # min(?*, (N % num<hreads F 1! D num<hreads!$
55device55 float funcion5)pu(float x!
"
return sin(1Dx!*poK(x,?!D(x % 1!*(x % *!$
(
float funcion5cpu(float x!
"
return sin(1Dx!*poK(x,?!D(x % 1!*(x % *!$
(
55)lo=al55 void trapecios(float a, float =, float h, float* resultado!
"
55shared55 float parcial&num<hreads'$
int iteracion # thread>dx.x % =loc@>dx.x* =loc@3im.x$
float temp # 0$
Khile ( iteracion < N !
"
;7
Captulo 4 Programacin paralela
if (iteracion L# 0!
temp %# funcion5)pu(a % h * iteracion!$
iteracion %# =loc@3im.x * )rid3im.x$
(
parcial&thread>dx.x' # temp$ DD 4lmacena los resultados parciales
55syncthreads(!$ DD Sincronia threads
int i # =loc@3im.x D *$
Khile ( iL#0 ! DD 6ase de reducciMn
"
if (thread>dx.x < i!
parcial&thread>dx.x' %# parcial&thread>dx.x % i'$
55syncthreads(!$
i D# *$
(
if (thread>dx.x ## 0!
resultado&=loc@>dx.x' # parcial&0'$
(
int main(int ar)c, char **ar)v!
"
const float a # 1.If$
const float = # *.NHf$
float h # (= F a! D N$
float *resultado5cpu$
float *resultado5)pu$
resultado5cpu # (float*!malloc(=loCues,or2rid * sieof(float!!$
+-345S4675+488(cuda9alloc(:resultado5)pu, =loCues,or2rid *
sieof(float!!!$
trapecios<<<=loCues,or2rid,num<hreads>>>(a, =, h, resultado5)pu!$
+-345S4675+488(cuda9emcpy(resultado5cpu, resultado5)pu,
=loCues,or2rid *sieof(float!, cuda9emcpy3evice<o;ost!!$
float suma5parciales # (funcion5cpu(a! % funcion5cpu(=!! D *.0f$
for (int i # 0$ i < =loCues,or2rid$ i%%!
suma5parciales %# resultado5cpu&i'$
suma5parciales *# h$
std//cout << 01esultado de inte)ral con 2,-/ 0 << suma5parciales <<
std//endl$

suma5parciales # (funcion5cpu(a! % funcion5cpu(=!! D *.0f$

, Carlos -im.nez de Parga ;/
Captulo 4 Programacin paralela
for(int i#1$ i<N$ i%%!
suma5parciales %# funcion5cpu(a % i*h!$
suma5parciales *# h$
std//cout << 01esultado de inte)ral con +,-/ 0 << suma5parciales <<
std//endl$
cuda6ree(resultado5)pu!$
free(resultado5cpu!$
return 0$
(
;;

También podría gustarte