Sei sulla pagina 1di 78

Primeros pasos con CUDA

Clase 1
Mnica Denham CONICET - UNRN

Ejemplo: suma de vectores

Comencemos con un ejemplo sencillo: suma de vectores.

Sean A, B y C vectores de dimensin N, la suma se define como:


C = A + B donde C
i
= A
i
+ B
i

Esta operacin suma cada elemento del A y B y lo almacen en C.



Suma de vectores
A
a

a
!
a
"
a
#
a
N$!
B
%

%
!
%
"
%
#
%
N$!

Suma de vectores
A
a

a
!
a
"
a
#
a
N$!
B
%

%
!
%
"
%
#
%
N$!
C
c

+
=

Suma de vectores
A
a

a
!
a
"
a
#
a
N$!
B
%

%
!
%
"
%
#
%
N$!
C
c

c
!
+ +
=

Suma de vectores
A
a

a
!
a
"
a
#
a
N$!
B
%

%
!
%
"
%
#
%
N$!
C
c

c
!
c
"
+ + +
=

Suma de vectores
A
a

a
!
a
"
a
#
a
N$!
B
%

%
!
%
"
%
#
%
N$!
C
c

c
!
c
"
c
#
c
N$!
+ + + +
=

Suma de vectores solucin &
/*
Suma de vectores secuencial
*/
vector'ops.cu
/* Suma de vectores (inplace) */
int vector_ops_suma_sec(float *v1, float *v2, int dim)
{
for (int i = 0; i < dim; i++) {
v1[i = v1[i + v2[i;
!
return 1;
!
vectorops!c"

Suma de vectores solucin &
/*
Suma de vectores secuencial
*/
vector'ops.cu
/* Suma de vectores (inplace) */
int vector_ops_suma_sec(float *v1, float *v2, int dim)
{
for (int i = 0; i < dim; i++) {
v1[i = v1[i + v2[i;
!
return 1;
!
Complejidad computacional lineal: ()N* donde N es la dimensin de los arre+los.
vectorops!c"

Suma de vectores solucin &
,iene orden de complejidad lineal, al aumentar el n-mero de
elementos aumenta linealmente la cantidad de operaciones.

Suma de vectores solucin &
,iene orden de complejidad lineal, al aumentar el n-mero de
elementos aumenta linealmente la cantidad de operaciones.
.ara vectores pe/ue0os la solucin
es correcta.

Suma de vectores solucin &
,iene orden de complejidad lineal, al aumentar el n-mero de
elementos aumenta linealmente la cantidad de operaciones.
.ara vectores pe/ue0os la solucin
es correcta.
.ara vectores muy +randes este
tipo de solucin puede ocasionar
penali1aciones en el tiempo de
cmputo.

Suma de vectores

2Cmo ser3a una solucin paralela4


Se puede paraleli1ar la suma el c5lculo de cada elemento del vector resultante es
independiente de los dem5s elementos del vector:
A
a

a
!
a
"
a
#
a
N$!
B
%

%
!
%
"
%
#
%
N$!
6
6

Suma de vectores
A
a

a
!
a
"
a
#
a
N$!
B
%

%
!
%
"
%
#
%
N$!
6
6
Si en ve1 de un -nico procesador tenemos
. procesadores, dividimos los c5lculos
entre los . procesadores.

2Cmo ser3a una solucin paralela4


Se puede paraleli1ar la suma el c5lculo de cada elemento del vector resultante es
independiente de los dem5s elementos del vector:

Suma de vectores
A
a

a
!
a
"
a
#
a
N$!
B
%

%
!
%
"
%
#
%
N$!
6
6
C
c

c
!
c
"
c
#
c
N$!
=
6
Si contamos con N procesadores,
reali1amos todos los c5lculos
al mismo tiempo.
# # # # # # #

2Cmo ser3a una solucin paralela4


Se puede paraleli1ar la suma, el c5lculo de cada elemento del vector resultante es
independiente de los dem5s elementos del vector:
c

c
!
c
"
c
#
c
N$!
6
=

Suma de vectores
A
a

a
!
a
"
a
#
a
N$!
B
%

%
!
%
"
%
#
%
N$!
6
6
C
c

c
!
c
"
c
#
c
N$!
6
Si contamos con N procesadores,
reali1amos todos los c5lculos
al mismo tiempo.
# # # # # # #
7e orden lineal a orden constante

2Cmo ser3a una solucin paralela4


Se puede paraleli1ar la suma, el c5lculo de cada elemento del vector resultante es
independiente de los dem5s elementos del vector:
=
8 se resuelve en paralelo todos los
resultados del vector.

Entonces...
,en+o una .C re linda...

Entonces...
,en+o una .C re linda...
,en+o una 9.: /ue me dicen /ue
es re linda...

Entonces...
,en+o una .C re linda...
,en+o una 9.: /ue me dicen /ue
es re linda...
,en+o dos vectores para sumar...
A
B
6

Entonces...
,en+o una .C re linda...
,en+o una 9.: /ue me dicen /ue
es re linda...
,en+o dos vectores para sumar...
22Cmo utili1o estas ar/uitecturas para
solucionar mi pro%lema44
A
B
6

C:7A )Compute :nified 7evice Arc;itecture*
CUDA es una arquitectura de software y hardware que permite a
GPUs ejecutar programas escritos en C, C++, Fortran, penC!,
DirectCompute y otro "enguajes#

C:7A )Compute :nified 7evice Arc;itecture*
CUDA es una arquitectura de software y hardware que permite a
GPUs ejecutar programas escritos en C, C++, Fortran, penC!,
DirectCompute y otro "enguajes#
:n pro+rama C:7A es un pro+ ra ma
;3%rido:

Cdi+o secuencial se ejecuta en C.:

Cdi+o paralelo se ejecuta en 9.:



C:7A

:n pro+rama C:7A invoca a kernels paralelos.

:n kernel se ejecuta en paralelo a trav<s threads paralelos.



C:7A

:n pro+rama C:7A invoca a kernels paralelos.

:n kernel se ejecuta en paralelo a trav<s threads paralelos.


El pro+ramador or+ani1a estos
t;reads en %lo/ues y +rids.

C:7A

:n pro+rama C:7A invoca a kernels paralelos.

:n kernel se ejecuta en paralelo a trav<s threads paralelos.


El pro+ramador o el compilador or+ani1a estos
t;reads en %lo/ues y +rids.
=erar/u3a de t;reads en cada >ernel:
$ ?os t;reads se or+ani1an en %lo/ues.

C:7A

:n pro+rama C:7A invoca a kernels paralelos.

:n kernel se ejecuta en paralelo a trav<s threads paralelos.


El pro+ramador or+ani1a estos
t;reads en %lo/ues y +rids.
=erar/u3a de t;reads en cada >ernel:
$ ?os t;reads se or+ani1an en %lo/ues.
$ ?os %lo/ues se or+ani1an en +rids.

C:7A

:n pro+rama C:7A invoca a kernels paralelos.

:n kernel se ejecuta en paralelo a trav<s threads paralelos.


El pro+ramador or+ani1a estos
t;reads en %lo/ues y +rids.
=erar/u3a de t;reads en cada >ernel:
$ ?os t;reads se or+ani1an en %lo/ues.
$ ?os %lo/ues se or+ani1an en +rids.
7esde la C.: se comanda
la ejecucin de t;reads en 9.:

C:7A

Cada t;read dentro de un %lo/ue ejecuta una instancia del >ernel.



C:7A

Cada t;read dentro de un %lo/ue ejecuta una instancia del >ernel.

Cada t;read tiene:

Su id dentro del %lo/ue, .C )pro+ram counter*


re+istros, memoria privada, inputs y outpus.

C:7A

Cada t;read dentro de un %lo/ue ejecuta una instancia del >ernel.

Cada t;read tiene:

Su id dentro del %lo/ue, .C )pro+ram counter*


re+istros, memoria privada, inputs y outpus.

?os t;reads dentro de un %lo/ue pueden cooperar


entre ellos mediante %arreras y memoria compartida.

Cada %lo/ue tiene su propio &7 dentro del +rid.

:n %lo/ue de t;reads es un conjunto de t;reads concurrentes:



C:7A

:n +rid es un arre+lo de %lo/ues de t;reads /ue:

Ejecutan el mismo >ernel.

?een@escri%en en memoria +lo%al.

Se pueden sincroni1ar.

C:7A

=erar/u3a de t;reads: t;read, %lo/ue y


+rid.

Aemorias:

.rivada de cada t;read.

Compartida por %lo/ue.

9lo%al de toda la aplicacin



C:7A

,enemos pro+ramas C:7A ;3%ridos, /ue se ejecutan en C.: y 9.:.



C:7A

,enemos pro+ramas C:7A ;3%ridos, /ue se ejecutan en C.: y 9.:.

,enemos dos ar/uitecturas /ue se conectan mediante un conector .C&$EBpress )no


comparten espacio de direccionamiento*

Suma de vectores
2Cmo lo ;acemos con C:7A4

Este pro%lema a;ora implica:



Suma de vectores
2Cmo lo ;acemos con C:7A4

Este pro%lema a;ora implica:

&niciali1acin de arre+los en C.:



Suma de vectores
2Cmo lo ;acemos con C:7A4

Este pro%lema a;ora implica:

&niciali1acin de arre+los en C.:

,ransferencia de datos C.: 9.:



Suma de vectores
2Cmo lo ;acemos con C:7A4

Este pro%lema a;ora implica:

&niciali1acin de arre+los en C.:

,ransferencia de datos C.: 9.:

C5lculo de la suma en paralelo.



Suma de vectores
2Cmo lo ;acemos con C:7A4

Este pro%lema a;ora implica:

&niciali1acin de arre+los en C.:

,ransferencia de datos C.: 9.:

C5lculo de la suma en paralelo.

,ransferencia de datos 9.: C.:.



Suma de vectores
2Cmo lo ;acemos con C:7A4

Este pro%lema a;ora implica:

&niciali1acin de arre+los en C.:

,ransferencia de datos C.: 9.:

C5lculo en 9.:.

,ransferencia de datos 9.: C.:.


Aodelo de pro+ramacin
C:7A

Suma de vectores
/*
Main.cu: suma de vectores. Cdigo que se ejecuta en host.
*/
main.cu
int main()
{
/* alocacion de memoria en "ost */
float *"#$ = (float *) malloc(% * sizeof(float));
float *"#& = (float *) malloc(% * sizeof(float));
float *"#au' = (float *) malloc(% * sizeof(float));
/* alocacion de memoria en device */
float *d#$, *d#&;
cuda(alloc((void**))d#$, sizeof(float) * %);
cuda(alloc((void**))d#&, sizeof(float) * %);
/* c"e*ueo de alocacion de memoria */
if (+"#$ ,, +"#& ,, +d#$ ,, +d#& ,, +"#au') {
print-(./rror alocando vectores 0n.);
e'it(11);
!
main!c"

Suma de vectores
/*
Main.cu: suma de vectores. Cdigo que se ejecuta en host.
*/
int main()
{
/* alocacion de memoria en "ost */
float *"#$ = (float *) malloc(% * sizeof(float));
float *"#& = (float *) malloc(% * sizeof(float));
float *"#au' = (float *) malloc(% * sizeof(float));
/* alocacion de memoria en device */
float *d#$, *d#&;
cuda(alloc((void**))d#$, sizeof(float) * %);
cuda(alloc((void**))d#&, sizeof(float) * %);
/* c"e*ueo de alocacion de memoria */
if (+"#$ ,, +"#& ,, +d#$ ,, +d#& ,, +"#au') {
print-(./rror alocando vectores 0n.);
e'it(11);
!
Alocacin de memoria
din5mica en ;ost
main.cu

Suma de vectores
/*
Main.cu: suma de vectores. Cdigo que se ejecuta en host.
*/
int main()
{
/* alocacion de memoria en "ost */
float *"#$ = (float *) malloc(% * sizeof(float));
float *"#& = (float *) malloc(% * sizeof(float));
float *"#au' = (float *) malloc(% * sizeof(float));
/* alocacion de memoria en device */
float *d#$, *d#&;
cuda(alloc((void**))d#$, sizeof(float) * %);
cuda(alloc((void**))d#&, sizeof(float) * %);
/* c"e*ueo de alocacion de memoria */
if (+"#$ ,, +"#& ,, +d#$ ,, +d#& ,, +"#au') {
print-(./rror alocando vectores 0n.);
e'it(11);
!
Alocacin de memoria
en device
main.cu
Aloca n %ytes en memoria +lo%al
del device los cuales ser5n apunta$
dos por d'A )d'B respectivamente*

Suma de vectores
/*
Main.cu: suma de vectores. Cdigo que se ejecuta en host.
*/
int main()
{
/* alocacion de memoria en "ost */
float *"#$ = (float *) malloc(% * sizeof(float));
float *"#& = (float *) malloc(% * sizeof(float));
float *"#au' = (float *) malloc(% * sizeof(float));
/* alocacion de memoria en device */
float *d#$, *d#&;
cuda(alloc((void**))d#$, sizeof(float) * %);
cuda(alloc((void**))d#&, sizeof(float) * %);
/* c"e*ueo de alocacion de memoria */
if (+"#$ ,, +"#& ,, +d#$ ,, +d#& ,, +"#au') {
print-(./rror alocando vectores 0n.);
e'it(11);
!
main.cu

Suma de vectores
/*
Continuacin del cdigo anterior
*/
/* iniciali2acion de vectores */
print-(.3niciali2acion vector $ 0n.);
vector#io#initiali2e4%5("#$, %);
print-(.3niciali2acion vector & 0n.);
vector#io#initiali2e4%5("#&, %);
/* trans-erencia de datos cpu 16 7pu ("ost 16 device) */
cuda(emcp8(d#$, "#$, sizeof(float) * %, cuda(emcp89ost:o5evice);
cuda(emcp8(d#&, "#&, sizeof(float) * %, cuda(emcp89ost:o5evice);
main.cu

Suma de vectores
/*
Contina cdigo anterior
*/
/* iniciali2acion de vectores */
print-(.3niciali2acion vector $ 0n.);
vector#io#initiali2e4%5("#$, %);
print-(.3niciali2acion vector & 0n.);
vector#io#initiali2e4%5("#&, %);
/* trans-erencia de datos cpu 16 7pu ("ost 16 device) */
cuda(emcp8(d#$, "#$, sizeof(float) * %, cuda(emcp89ost:o5evice);
cuda(emcp8(d#&, "#&, sizeof(float) * %, cuda(emcp89ost:o5evice);
main.cu

Suma de vectores
/*
Contina cdigo anterior
*/
/* iniciali2acion de vectores */
print-(.3niciali2acion vector $ 0n.);
vector#io#initiali2e4%5("#$, %);
print-(.3niciali2acion vector & 0n.);
vector#io#initiali2e4%5("#&, %);
/* trans-erencia de datos cpu 16 7pu ("ost 16 device) */
cuda(emcp8(d#$, "#$, sizeof(float) * %, cuda(emcp89ost:o5evice);
cuda(emcp8(d#&, "#&, sizeof(float) * %, cuda(emcp89ost:o5evice);
C.:
Aemoria
principal
9.:
Aemoria
+lo%al
&@(
main.cu

Suma de vectores
/*
Contina cdigo anterior
*/
/* iniciali2acion de vectores */
print-(.3niciali2acion vector $ 0n.);
vector#io#initiali2e4%5("#$, %);
print-(.3niciali2acion vector & 0n.);
vector#io#initiali2e4%5("#&, %);
/* trans-erencia de datos cpu 16 7pu ("ost 16 device) */
cuda(emcp8(d#$, "#$, sizeof(float) * %, cuda(emcp89ost:o5evice);
cuda(emcp8(d#&, "#&, sizeof(float) * %, cuda(emcp89ost:o5evice);
C.:
Aemoria
principal
9.:
Aemoria
+lo%al
&@(
main.cu

Suma de vectores
/*
Main.cu: suma de vectores. Cdigo que se ejecuta en host.
*/
Copia datos de
;ost a device
C.:
Aemoria
principal
9.:
Aemoria
+lo%al
&@(
/* iniciali2acion de vectores */
print-(.3niciali2acion vector $ 0n.);
vector#io#initiali2e4%5("#$, %);
print-(.3niciali2acion vector & 0n.);
vector#io#initiali2e4%5("#&, %);
/* trans-erencia de datos cpu 16 7pu ("ost 16 device) */
cuda(emcp8(d#$, "#$, sizeof(float) * %, cuda(emcp89ost:o5evice);
cuda(emcp8(d#&, "#&, sizeof(float) * %, cuda(emcp89ost:o5evice);
main.cu

Suma de vectores
/*
Main.cu: suma de vectores. Cdigo que se ejecuta en host.
*/
Copia datos de
;ost a device
/* iniciali2acion de vectores */
print-(.3niciali2acion vector $ 0n.);
vector#io#initiali2e4%5("#$, %);
print-(.3niciali2acion vector & 0n.);
vector#io#initiali2e4%5("#&, %);
/* trans-erencia de datos cpu 16 7pu ("ost 16 device) */
cuda(emcp8(d#$, "#$, sizeof(float) * %, cuda(emcp89ost:o5evice);
cuda(emcp8(d#&, "#&, sizeof(float) * %, cuda(emcp89ost:o5evice);
main.cu
cudaMemcpy(destino, origen, size, DIRECCION_COPIA)
Copia si1e %ytes desde la direccin ori+en a la direccin
destino en la memoria +lo%al. 7&CECC&(N'C(.&A indica
el sentido de la copia:
$ cudaAemcpyDost,oDost.
$ cudaAemcpyDost,o7evice.
$ cudaAemcpy7evice,oDost.
$ cudaAemcpy7evice,o7evice.

Suma de vectores
/*
Main.cu: suma de vectores. Cdigo que se ejecuta en host.
*/
C.:
Aemoria
principal
9.:
Aemoria
+lo%al
&@(
/* iniciali2acion de vectores */
print-(.3niciali2acion vector $ 0n.);
vector#io#initiali2e4%5("#$, %);
print-(.3niciali2acion vector & 0n.);
vector#io#initiali2e4%5("#&, %);
/* trans-erencia de datos cpu 16 7pu ("ost 16 device) */
cuda(emcp8(d#$, "#$, sizeof(float) * %, cuda(emcp89ost:o5evice);
cuda(emcp8(d#&, "#&, sizeof(float) * %, cuda(emcp89ost:o5evice);
,enemos los datos alocados en memoria principal
de la C.: y en memoria +lo%al de 9.:.
Estamos listos para operar en device.
main.cu

Suma de vectores
/*
Main.cu: continuacin del cdigo.
*/
main.cu
/* suma secuencial */
printf("Suma secuencial (CPU)\n");
suma_secuencial(h_A, h_B, N);
/* suma paralela */
printf("Suma paralela (PU) \n");
suma_paralela(!_A, !_B, N);
/* trai"# l#s !at#s !es!e PU a CPU para testear la suma */
cu!a$emcp%(h_au&, !_A, si'e#f(fl#at) * N, cu!a$emcp%(e)ice*#+#st);
if()ect#r_#ps_i"uales(h_au&, h_A, N))
printf("*est pasa!#, \n");
else
printf("*est n# pasa!#, \n");
/* li-eraci#n !e mem#ria */
free(h_A);
free(h_B);
free(h_au&);
cu!a.ree(!_A);
cu!a.ree(!_B);
return /;
0

Suma de vectores
/*
Main.cu: continuacin del cdigo.
*/
/* suma secuencial */
printf("Suma secuencial (CPU)\n");
suma_secuencial(h_A, h_B, N);
/* suma paralela */
printf("Suma paralela (PU) \n");
suma_paralela(!_A, !_B, N);
/* trai"# l#s !at#s !es!e PU a CPU para testear la suma */
cu!a$emcp%(h_au&, !_A, si'e#f(fl#at) * N, cu!a$emcp%(e)ice*#+#st);
if()ect#r_#ps_i"uales(h_au&, h_A, N))
printf("*est pasa!#, \n");
else
printf("*est n# pasa!#, \n");
/* li-eraci#n !e mem#ria */
free(h_A);
free(h_B);
free(h_au&);
cu!a.ree(!_A);
cu!a.ree(!_B);
return /;
0
Euncin secuencial, ya vista
main.cu

Suma de vectores
/*
Main.cu: continuacin del cdigo.
*/
/* suma secuencial */
printf("Suma secuencial (CPU)\n");
suma_secuencial(h_A, h_B, N);
/* suma paralela */
printf("Suma paralela (PU) \n");
suma_paralela(!_A, !_B, N);
/* trai"# l#s !at#s !es!e PU a CPU para testear la suma */
cu!a$emcp%(h_au&, !_A, si'e#f(fl#at) * N, cu!a$emcp%(e)ice*#+#st);
if()ect#r_#ps_i"uales(h_au&, h_A, N))
printf("*est pasa!#, \n");
else
printf("*est n# pasa!#, \n");
/* li-eraci#n !e mem#ria */
free(h_A);
free(h_B);
free(h_au&);
cu!a.ree(!_A);
cu!a.ree(!_B);
return /;
}
Euncin paralela
main.cu

Suma de vectores
/*
Funcin que invoca al kernel desde C!" se invoca a kernel #!"$$
*/
/* Suma de vectores. %esultado queda en el &rimer argumento */
int vector_ops_suma_parfloat *v'( float *v)( int dim$
*
dim+ n,hreads-')$.
dim+ n/locksdim / n,hreads.0$ 1 dim 2 n,hreads.0 3 ' : 4$$.
kernel5suma666n/locks( n,hreads777v'( v)( dim$.
cuda8eviceS9nchroni:e$.
return '.
}
vector'ops.c

Suma de vectores
/*
Funcin que invoca al kernel desde C!" se invoca a kernel #!"$$
*/
Confi+uracin
del +rid
/* Suma de vectores. %esultado queda en el &rimer argumento */
int vector_ops_suma_parfloat *v'( float *v)( int dim$
*
dim+ n,hreads-')$.
dim+ n/locksdim / n,hreads.0$ 1 dim 2 n,hreads.0 3 ' : 4$$.
kernel5suma666n/locks( n,hreads777v'( v)( dim$.
cuda8eviceS9nchroni:e$.
return '.
}
vector'ops.c
Faria%les de tipo dim! vector de # enteros /ue se usa para especificar dimensiones.
Componentes B, y, 1. Si al+-n componente no se iniciali1a !.

Suma de vectores
/*
Funcin que invoca al kernel desde C!" se invoca a kernel #!"$$
*/
Confi+uracin
del +rid
/* Suma de vectores. %esultado queda en el &rimer argumento */
int vector_ops_suma_parfloat *v'( float *v)( int dim$
*
dim+ n,hreads-')$.
dim+ n/locksdim / n,hreads.0$ 1 dim 2 n,hreads.0 3 ' : 4$$.
kernel5suma666n/locks( n,hreads777v'( v)( dim$.
cuda8eviceS9nchroni:e$.
return '.
}
vector'ops.c
Faria%les de tipo dim! vector de # enteros /ue se usa para especificar dimensiones.
Componentes B, y, 1. Si al+-n componente no se iniciali1a !.
n,;reads especificar5 cantidad de t;reads por %lo/ue.
nBloc>s especificar5 cantidad de %lo/ues en el +rid

Suma de vectores
/*
Funcin que invoca al kernel desde C!" se invoca a kernel #!"$$
*/
Confi+uracin
del +rid
/* Suma de vectores. %esultado queda en el &rimer argumento */
int vector_ops_suma_parfloat *v'( float *v)( int dim$
*
dim+ n,hreads-')$.
dim+ n/locksdim / n,hreads.0$ 1 dim 2 n,hreads.0 3 ' : 4$$.
kernel5suma666n/locks( n,hreads777v'( v)( dim$.
cuda8eviceS9nchroni:e$.
return '.
}
vector'ops.c
Faria%les de tipo dim! vector de # enteros /ue se usa para especificar dimensiones.
Componentes B, y, 1. Si al+-n componente no se iniciali1a !.
n,;reads especificar5 cantidad de t;reads por %lo/ue )%lo/ues de !, " o # dimensiones*.
nBloc>s especificar5 cantidad de %lo/ues en el +rid )+rids de !, " o # dimensiones*
"C#mo $ueda con%igurado e& grid'

Gernel !:

dim# dim9rid)#,"*

dim# dimBloc>)H,#*

Gernel ":

dim# dim9rid)I,#*

7im# dimBloc>)4,4,4*

Suma de vectores
/*
Funcin se ejecuta en C!"$ que invoca al kernel se ejecuta en #!"$
*/
?an1amiento
del >ernel
/* Suma de vectores. %esultado queda en el &rimer argumento */
int vector_ops_suma_parfloat *v'( float *v)( int dim$
*
dim+ n,hreads-')$.
dim+ n/locksdim / n,hreads.0$ 1 dim 2 n,hreads.0 3 ' : 4$$.
kernel5suma666n/locks( n,hreads777v'( v)( dim$.
cuda8eviceS9nchroni:e$.
return '.
}
vector'ops.c

Suma de vectores
/*
Funcin se ejecuta en C!"$ que invoca al kernel se ejecuta en #!"$
*/
?an1amiento
del >ernel
/* Suma de vectores. %esultado queda en el &rimer argumento */
int vector_ops_suma_parfloat *v'( float *v)( int dim$
*
dim+ n,hreads-')$.
dim+ n/locksdim / n,hreads.0$ 1 dim 2 n,hreads.0 3 ' : 4$$.
kernel5suma666n/locks( n,hreads777v'( v)( dim$.
cuda8eviceS9nchroni:e$.
return '.
}
vector'ops.c
nom(re_)erne&***n+mero de (&o$ues, t,reads por (&o$ue---(par.metros actua&es)J

Suma de vectores
/*
Funcin se ejecuta en C!"$ que invoca al kernel se ejecuta en #!"$
*/
Gernel
/* Suma de vectores. %esultado queda en el &rimer argumento */
int vector_ops_suma_parfloat *v'( float *v)( int dim$
*
dim+ n,hreads-')$.
dim+ n/locksdim / n,hreads.0$ 1 dim 2 n,hreads.0 3 ' : 4$$.
kernel5suma666n/locks( n,hreads777v'( v)( dim$.
cuda8eviceS9nchroni:e$.
return '.
}
/* suma !e ca!a element# !el )ect#r */
__"l#-al__ )#i! 1ernel_suma(fl#at *)2, fl#at *)3, int !im)
4
int i! 5 threa!6!&7& 8 (-l#c16!&7& * -l#c1(im7&);
if (i! 9 !im)
4
)2:i!; 5 )2:i!; 8 )3:i!;;
0
0
vector'ops.c

Suma de vectores
/*
Main.cu: continuacin del cdigo.
*/
/* Suma de vectores. %esultado queda en el &rimer argumento */
int vector_ops_suma_parfloat *v'( float *v)( int dim$
*
dim+ n,hreads-')$.
dim+ n/locksdim / n,hreads.0$ 1 dim 2 n,hreads.0 3 ' : 4$$.
kernel5suma666n/locks( n,hreads777v'( v)( dim$.
cuda8eviceS9nchroni:e$.
return '.
}
/* suma !e ca!a element# !el )ect#r */
__"l#-al__ )#i! 1ernel_suma(fl#at *)2, fl#at *)3, int !im)
4
int i! 5 threa!6!&7& 8 (-l#c16!&7& * -l#c1(im7&);
if (i! 9 !im)
4
)2:i!; 5 )2:i!; 8 )3:i!;;
0
0
vector'ops.c
__g&o(a&__: calificador de funcin

Calificadores de funciones:
''+lo%al'': determina /ue es una funcin >ernel, se ejecuta en el
dispositivo y slo puede ser invocada desde el ;ost.
Su invocacin +enera un +rid de %lo/ues con n-mero fijo
e i+ual de t;reads.
''device'' : es una funcin del dispositivo, se ejecuta en <l y slo
puede ser invocada desde un >ernel u otra funcin del
dispositivo.
'';ost'' : determina /ue es una funcin del ;ost, o simplemente
una funcin de C tradicional a ejecutarse en ;ost y /ue
puede ser invocada desde ;ost. .or omisin.

Suma de vectores
/*
Main.cu: continuacin del cdigo.
*/
vector'ops.c
/* Suma de vectores. %esultado queda en el &rimer argumento */
int vector_ops_suma_parfloat *v'( float *v)( int dim$
*
dim+ n,hreads-')$.
dim+ n/locksdim / n,hreads.0$ 1 dim 2 n,hreads.0 3 ' : 4$$.
kernel5suma666n/locks( n,hreads777v'( v)( dim$.
cuda8eviceS9nchroni:e$.
return '.
}
/* suma !e ca!a element# !el )ect#r */
__"l#-al__ )#i! 1ernel_suma(fl#at *)2, fl#at *)3, int !im)
4
int i! 5 threa!6!&7& 8 (-l#c16!&7& * -l#c1(im7&);
if (i! 9 !im)
4
)2:i!; 5 )2:i!; 8 )3:i!;;
0
0

Faria%les reservadas:
gridDim: contiene las dimensiones del +rid.
(&oc/Id0 : contiene el identificador del %lo/ue en un +rid.
(&oc/Dim: contiene las dimensiones del %lo/ue.
t,readId0: contiene el identificador del t;read dentro del %lo/ue.
1odas tienen componentes 0,y,z2

3rids y (&o$ues de 4, 5 o dimensiones2

Suma de vectores
/*
Main.cu: continuacin del cdigo.
*/
vector'ops.c
/* Suma de vectores. %esultado queda en el &rimer argumento */
int vector_ops_suma_parfloat *v'( float *v)( int dim$
*
dim+ n,hreads-')$.
dim+ n/locksdim / n,hreads.0$ 1 dim 2 n,hreads.0 3 ' : 4$$.
kernel5suma666n/locks( n,hreads777v'( v)( dim$.
cuda8eviceS9nchroni:e$.
return '.
}
/* suma !e ca!a element# !el )ect#r */
__"l#-al__ )#i! 1ernel_suma(fl#at *)2, fl#at *)3, int !im)
4
int i! 5 threa!6!&7& 8 (-l#c16!&7& * -l#c1(im7&);
if (i! 9 !im)
4
)2:i!; 5 )2:i!; 8 )3:i!;;
0
0

Suma de vectores
/*
Main.cu: continuacin del cdigo.
*/
vector'ops.c
/* Suma de vectores. %esultado queda en el &rimer argumento */
int vector_ops_suma_parfloat *v'( float *v)( int dim$
*
dim+ n,hreads-')$.
dim+ n/locksdim / n,hreads.0$ 1 dim 2 n,hreads.0 3 ' : 4$$.
kernel5suma666n/locks( n,hreads777v'( v)( dim$.
cuda8eviceS9nchroni:e$.
return '.
}
/* suma !e ca!a element# !el )ect#r */
__"l#-al__ )#i! 1ernel_suma(fl#at *)2, fl#at *)3, int !im)
4
int i! 5 threa!6!&7& 8 (-l#c16!&7& * -l#c1(im7&);
if (i! 9 !im)
4
)2:i!; 5 )2:i!; 8 )3:i!;;
0
0
Cada t;read resuelve
un -nico elemento del
vector.

Suma de vectores
/*
Main.cu: continuacin del cdigo.
*/
main.cu
/* suma secuencial */
print-(.Suma secuencial (;<=)0n.);
suma#secuencial("#$, "#&, %);
/* suma paralela */
print-(.Suma paralela (><=) 0n.);
suma#paralela(d#$, d#&, %);
/* trai7o los datos desde ><= a ;<= para testear la suma */
cuda(emcp8("#au', d#$, sizeof(float) * %, cuda(emcp85evice:o9ost);
if(vector#ops#i7uales("#au', "#$, %))
print-(.:est pasado+ 0n.);
else
print-(.:est no pasado+ 0n.);
/* li?eracion de memoria */
-ree("#$);
-ree("#&);
-ree("#au');
cuda@ree(d#$);
cuda@ree(d#&);
return 0;
!

Suma de vectores
/*
Main.cu: continuacin del cdigo.
*/
main.cu
/* suma secuencial */
print-(.Suma secuencial (;<=)0n.);
suma#secuencial("#$, "#&, %);
/* suma paralela */
print-(.Suma paralela (><=) 0n.);
suma#paralela(d#$, d#&, %);
/* trai7o los datos desde ><= a ;<= para testear la suma */
cuda(emcp8("#au', d#$, sizeof(float) * %, cuda(emcp85evice:o9ost);
if(vector#ops#i7uales("#au', "#$, %))
print-(.:est pasado+ 0n.);
else
print-(.:est no pasado+ 0n.);
/* li?eracion de memoria */
-ree("#$);
-ree("#&);
-ree("#au');
cuda@ree(d#$);
cuda@ree(d#&);
return 0;
!

Suma de vectores
/*
Main.cu: continuacin del cdigo.
*/
main.cu
/* suma secuencial */
print-(.Suma secuencial (;<=)0n.);
suma#secuencial("#$, "#&, %);
/* suma paralela */
print-(.Suma paralela (><=) 0n.);
suma#paralela(d#$, d#&, %);
/* trai7o los datos desde ><= a ;<= para testear la suma */
cuda(emcp8("#au', d#$, sizeof(float) * %, cuda(emcp85evice:o9ost);
if(vector#ops#i7uales("#au', "#$, %))
print-(.:est pasado+ 0n.);
else
print-(.:est no pasado+ 0n.);
/* li?eracion de memoria */
-ree("#$);
-ree("#&);
-ree("#au');
cuda@ree(d#$);
cuda@ree(d#&);
return 0;
!

Suma de vectores
/*
Main.cu: continuacin del cdigo.
*/
main.cu
/* suma secuencial */
print-(.Suma secuencial (;<=)0n.);
suma#secuencial("#$, "#&, %);
/* suma paralela */
print-(.Suma paralela (><=) 0n.);
suma#paralela(d#$, d#&, %);
/* trai7o los datos desde ><= a ;<= para testear la suma */
cuda(emcp8("#au', d#$, sizeof(float) * %, cuda(emcp85evice:o9ost);
if(vector#ops#i7uales("#au', "#$, %))
print-(.:est pasado+ 0n.);
else
print-(.:est no pasado+ 0n.);
/* li?eracion de memoria */
-ree("#$);
-ree("#&);
-ree("#au');
cuda@ree(d#$);
cuda@ree(d#&);
return 0;
!

Suma de vectores
A
a

a
!
a
"
a
#
a
N$!
B
%

%
!
%
"
%
#
%
N$!
6
6
C
c

c
!
c
"
c
#
c
N$!
6
# # # # # # #
7e orden lineal a orden constanteKK
=
8 se resuelve en paralelo todos los
resultados del vector.
t;

t;
!
t;
"
t;
#
t;
N$!
6

Cesumen
Demos visto:
$ Alocacin de memoria en device.
$ ,ransferencia de memoria ;ost device. $
$ Confi+uracin de +rid.
$ ?an1amiento de >ernels.
,odas estas operaciones las ofrece C:7A como una li%rer3a /ue eBtiende
al len+uaje C )en este caso*.

.roducto escalar
El modelo de ejecucin C:7A es ;3%rido: el mismo pro+rama contiene:

Cdi+o secuencial se ejecuta en C.:.

Cdi+o paralelo se ejecuta en 9.:.



Suma de vectores
El modelo de ejecucin C:7A es ;3%rido: el mismo pro+rama contiene:

Cdi+o secuencial se ejecuta en C.:.

Cdi+o paralelo se ejecuta en 9.:.



.roducto escalar
Dasta a;ora:
,enemos los datos alocados en memoria principal de la C.: y en memoria +lo%al
del device.

Estamos listos para operar en device.


C.:
Aemoria
principal
9.:
Aemoria
+lo%al
&@(

.roducto escalar
El modelo de ejecucin C:7A es ;3%rido: el mismo pro+rama contiene:

Cdi+o secuencial se ejecuta en C.:.

Cdi+o paralelo se ejecuta en 9.:.

Potrebbero piacerti anche