Documentos de Académico
Documentos de Profesional
Documentos de Cultura
herramientas de computacion
paralela
16 de marzo de 2017
0.1. Introducci
on
Como herramienta para la computacion paralela es-
ta guia pretende mostrar fundamentos basico de distintos
mecanismos en los que se desarrolla este paradigma, para
ello partimos que entre todas estas herramientas desarro-
llen la misma funcion, que en este caso sera el calculo del
numero pi, para que de este modo se pueda explicar cada
una de ellas por separado y futuramente realizarse una
comparacion con respecto a su proceso y el numero de
hilos que cada uno de estos lenguajes maneje.
1
2
0.2. Calculo de pi
En matematicas, la formula de Leibniz para el calculo
de , nombrada as en honor a Gottfried Leibniz, dice
que:
4
= 1 31 + 15 17 + 91 ...
X (x)n
=
4 n=0 2n + 1
0.3. Posix
Posix es una herramienta que permite realizar proce-
sos en paralelo, a traves de su menejo de hilos, imple-
mentando la libreria <pthread.h> a traves del lenguaje
C/C++. En el calculo de pi se implementa en posix de
la siguiente manera:
#define NUM 2
double p i [NUM] ;
struct g {
int pos , i n i , f i n ;
};
4
void c a l c u l a r P i ( void a ) {
int i ;
struct g l = ( struct g ) a ;
i = l >i n i ;
f l o a t s i g n o = 1;
i f ( i % 2 == 0 ) {
signo = 1;
}
do {
p i [ l >pos ] = p i [ l >pos ] + ( s i g n o / ( ( 2
i ) + 1) ) ;
i ++;
s i g n o = 1;
} while ( i < l >f i n ) ;
}
0.4. CUDA
CUDA es una arquitectura de calculo paralelo de NVI-
DIA que aprovecha la gran potencia de la GPU (unidad
de procesamiento grafico) para proporcionar un incre-
mento extraordinario del rendimiento del sistema. CUDA
proporciona unas cuantas extensiones de C y C++ que
permiten implementar el paralelismo en el procesamiento
de tareas y datos con diferentes niveles de granularidad.
El programador puede expresar ese paralelismo mediante
diferentes lenguajes de alto nivel como C, C++.
CUDA maneja el concepto de bloque, sientdo este una
agrupacion de hilos para asi compratir informacion entre
ellos de manera facil y dinamica.
En el calculo de pi el codigo contara con la funcion
global calculatePi que es la funcion a paralelizar, en
ella determina el hilo que se esta ejecutando, por medio
del id del bloque que lo maneja y la dimension de esta
a traves de(blockDim.x * blockIdx.x) + threadIdx.x. Se-
Determina el indice delimitando el funcinamiento del por
medio de las variables initIterator y endIterator. Den-
tro del ciclo do()while se realizan dos sumas una positi-
va y otra negativa imitando la formula Leibiniz, gracias
a que dentro del bucle las variable i se incrementa dos
veces, obteniendo el valor definitvo se asigna al arreglo
piTotal en la posicion index, para concluir con la sin-
cronizacion de hilos syncthreads(); que consiste en
convertir la posicion 0 de piTotal como el acumulador
8
syncthreads () ;
i f ( i n d e x == 0 ) {
f o r ( i = 1 ; i < t o t a l T h r e a d s ; i ++)
piTotal [ 0 ] = piTotal [ 0 ] + piTotal [ i
];
}
}
s s c a n f ( argv [ 1 ] , %i , &b l o c k s P e r G r i d ) ;
cudaError t e r r = cudaSuccess ;
s i z e = s i z e o f ( double ) NUMTHREADS;
h p i t o t a l = ( double ) m a l l o c ( s i z e ) ;
threadsPerBlock , totalThreads ) ;
c a l c u l a t e P i <<<b l o c k s P e r G r i d , t h r e a d s P e r B l o c k
>>>(d p i t o t a l , i t e r a t i o n s , t o t a l T h r e a d s )
;
e r r = cudaGetLastError ( ) ;
i f ( e r r != c u d a S u c c e s s ) {
f p r i n t f ( stderr , Failed to launch
vectorAdd k e r n e l ( e r r o r code %s ) ! \ n
, cudaGetErrorString ( err ) ) ;
e x i t (EXIT FAILURE) ;
}
e r r = cudaMemcpy ( h p i t o t a l , d p i t o t a l , s i z e ,
cudaMemcpyDeviceToHost ) ;
i f ( e r r != c u d a S u c c e s s ) {
f p r i n t f ( s t d e r r , F a i l e d t o copy v e c t o r C
from d e v i c e t o h o s t ( e r r o r code %s )
! \ n , c u d a G e t E r r o r S t r i n g ( e r r ) ) ;
e x i t (EXIT FAILURE) ;
}
e r r = cudaFree ( d p i t o t a l ) ;
i f ( e r r != c u d a S u c c e s s ) {
f p r i n t f ( stderr , Failed to f r e e device
v e c t o r C ( e r r o r code %s ) ! \ n ,
cudaGetErrorString ( err ) ) ;
e x i t (EXIT FAILURE) ;
}
p r i n t f ( \n %.12 f , h p i t o t a l ) ;
// Free h o s t memory
free ( h pitotal ) ;
11
e r r = cudaDeviceReset ( ) ;
i f ( e r r != c u d a S u c c e s s ) {
f p r i n t f ( stderr , Failed to d e i n i t i a l i z e
t h e d e v i c e ! e r r o r= %s \n ,
cudaGetErrorString ( err ) ) ;
e x i t (EXIT FAILURE) ;
}
0.5. OpenMP
OpenMP es una interfaz de programacion de apli-
caciones (API) para la programacion multiproceso de
memoria compartida en m ultiples plataformas. Permite
a
nadir concurrencia a los programas escritos en C y C++
y Fortran sobre la base del modelo de ejecucion fork-join.
Se compone de un conjunto de directivas de compilador,
rutinas de biblioteca, y variables de entorno que influyen
el comportamiento en tiempo de ejecucion.
Para el desarrollo de pi con OpenMP se procede de
la sigiuiente manera:
#include <omp . h>
s t a t i c long num steps = 1 0 0 0 0 0 ;
double s t e p ;
#define NUM THREADS 2
void main ( ) {
int i , n t h r e a d s ; double pi , sum [NUM
THREADS ] ;
s t e p = 1 . 0 / ( double ) num s t e p s ;
o m p s e t n u m t h r e a d s (NUM THREADS) ;
12
#p r a g m a o m p p a r a l l e l {
int i , id , n t h r d s ;
double x ;
i d = omp get thread num ( ) ;
n t h r d s = omp get num threads ( ) ;
i f ( i d == 0 ) n t h r e a d s = n t h r d s ;
f o r ( i=id , sum [ i d ] = 0 . 0 ; i <
num steps ; i=i+n t h r d s ) {
x=( i +0.5) s t e p ;
sum [ i d ] += 4 . 0 / ( 1 . 0 + xx )
;
}
}
f o r ( i =0, p i = 0 . 0 ; i <n t h r e a d s ; i ++)p i += sum
[ i ] step ;
}
paralelizar
omp get thread num() Obtiene la cantidad de hilos
en el programa para asignarlos a una variable.
0.6. Conclusiones
Gracias a las distintos a las distintas herramientas uti-
liadas en computacion paralela, el calculo de pi se puede
realizar en multiples plataformas, no cambiando su com-
portamiento matematico de ser una serie geometrica.
Muchas herramientas de la computacion paralela estan
implementadas en C/C++ gracias al manero de apunta-
dores y manejo de memoria esencial para el manejo de
multiples hilos y facilitando su manejo.
14
0.7. Bibliografa
1. Calculo de pi tomado de: https://es.wikipedia.
org/wiki/Serie_de_Leibniz