Práctica 4: Hebras Objetivos Makefile Pthreads: API Pthreads

Objetivos
Práctica 4: Hebras
Aprender a gestionar hebras utilizando Pthreads.
Gustavo Romero
Calcular cuánto tarda en ejecutarse el proceso nulo y la hebra
nula.
Arquitectura y Tecnologı́a de Computadores
Implementar una versión multihebra de la serie de Fibonacci.
10 de febrero de 2016
c Gustavo Romero
c Gustavo Romero
Práctica 4 (1/12)
Makefile
Práctica 4 (2/12)
Pthreads: API
http://pccito.ugr.es/~gustavo/aco/practicas/practica4/Makefile
SHELL=/ b i n / b a s h
DIR=$ ( s h e l l f i n d −mi ndepth 1 −maxdepth 1 −t y p e d )
SRC = $ ( w i l d c a r d ∗ . c c )
EXE = $ ( basename $ (SRC ) )
CXXFLAGS = −g3 −O3 −s t d=c++0x −W al l −Wl,−−no−as−n e e d
LDFLAGS = −l p t h r e a d − l r t
default :
$ (EXE)
#include <pthread.h>
función
pthread create(id,
attr, func, arg)
pthread exit(val)
pthread join(id, val)
pthread self()
all :
test
@ f o r d i n $ ( DIR ) ; do $ (MAKE) −C $$d $@ ; done
pthread yield()
clean :
c Gustavo Romero
Práctica 4 (3/12)
$ (RM) $ (EXE) ∗ . tmp c o r e . ∗ ∗˜
Pthreads: ejemplo.cc
descripción
crea una hebra mediante la ejecución
de la función func
finaliza un hebra y devuelve un valor
para otra que quiera esperarla
espera una hebra que finaliza y
recupera el valor que devuelve
devuelve el identificador de la hebra
con tipo pthread t
ceder el procesador voluntariamente
c Gustavo Romero
Práctica 4 (4/12)
Proceso nulo y hebra nula
http://pccito.ugr.es/~gustavo/aco/practicas/practica4/ejemplo.cc
proceso nulo
#i n c l u d e <p t h r e a d . h>
#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;
void ∗ hebra ( void ∗)
{
c o u t << ” [ 2 ] h o l a : ” << p t h r e a d s e l f ( ) << e n d l ;
p t h r e a d e x i t (NULL ) ; // e q u i v a l e n t e a r e t u r n NULL ;
}
i n t main ( )
{
pthread t id ;
i n t main ( )
{
return 0;
}
hebra nula
c o u t << ” [ 1 ] h o l a : ” << p t h r e a d s e l f ( ) << e n d l ;
p t h r e a d c r e a t e (& i d , NULL , h e b r a , NULL ) ;
p t h r e a d j o i n ( i d , NULL ) ;
return 0;
void ∗ hebra ( void ∗)
{
r e t u r n NULL ;
}
}
c Gustavo Romero
c Gustavo Romero
Práctica 4 (5/12)
Tiempo de ejecución del proceso nulo y de la hebra nula
Práctica 4 (6/12)
clock gettime() y clock getres()
http://pccito.ugr.es/~gustavo/aco/practicas/practica4/gettime.cc
¿Cuál es la forma más precisa de medir el tiempo de
ejecución? =⇒ ciclos de reloj.
¿Cómo medir los ciclos de reloj que tarda algo en ejecutarse?
=⇒ mediante la instrucción rdtsc.
¿Es suficiente? =⇒ NO: repetir el cálculo para “calentar” la
caché y hacer media para evitar las distorsiones introducidas
por el SO.
Conveniente sólo para reducidos conjuntos de instrucciones no
para largas secciones o cuando haya llamadas al sistema.
Alternativa para medir tiempos de ejecución:
clock gettime =⇒ precisión: nanosegundos.
gettimeofday =⇒ precisión: microsegundos.
getrusage =⇒ precisión: microsegundos.
clock =⇒ precisión: ticks del reloj.
time =⇒ precisión: milisegundos.
Para utilizar estas funciones es necesario soporte del núcleo
del SO y compilar la opción de tiempo real: LDFLAGS = -lrt
gettime.cc
f o r ( i n t i = 0 ; i < N ; ++i )
{
c l o c k g e t t i m e ( CLOCK REALTIME , &t s ) ;
c l o c k g e t t i m e ( CLOCK REALTIME , &t s 2 ) ;
sum += d i f f = ( t s 2 . t v s e c − t s . t v s e c ) ∗
1000000000 + ( t s 2 . t v n s e c − t s . t v n s e c ) ;
i f ( d i f f < min )
min = d i f f ;
}
Hoy utilizaremos clock gettime y clock getres.
c Gustavo Romero
Práctica 4 (7/12)
c Gustavo Romero
Práctica 4 (8/12)
La serie de Fibonacci
fib.cc I
http://pccito.ugr.es/~gustavo/aco/practicas/practica4/fib.cc
El programa debe recibir como argumento un número y escribir en la
salida estándar su correspondiente valor de la función de Fibonacci.
La hebra principal puede calcular por si sóla los casos base: 0 y 1.
En otro caso debe crear 2 hebras para calcular los valores de la
función para (n − 1) y (n − 2) y escribir por pantalla la suma.
Comparar mediante la orden time la velocidad de ejecución de las
versiones monohebra y multihebra.
fibonacci
unsigned fibonacci(unsigned n)
{
if (n < 2)
return n;
else
return fibonacci(n - 1) + fibonacci(n - 2);
}
c Gustavo Romero
#i n c l u d e
#i n c l u d e
#i n c l u d e
#i n c l u d e
u s i n g namespace s t d ;
int fib ( int n)
{
i f ( n < 2)
return n ;
else
r e t u r n f i b ( n − 1) + f i b ( n − 2) ;
}
i n t main ( i n t a r g c , c h a r ∗ a r g v [ ] )
{
try
{
i f ( argc < 2)
c Gustavo Romero
Práctica 4 (9/12)
fib.cc II
<c s t d l i b >
<i o s t r e a m >
<s s t r e a m >
<s t d e x c e p t >
Práctica 4 (10/12)
fib.cc III
http://pccito.ugr.es/~gustavo/aco/practicas/practica4/fib.cc
http://pccito.ugr.es/~gustavo/aco/practicas/practica4/fib.cc
throw i n v a l i d a r g u m e n t ( ” n e c e s i t o un numero como
parametro ” ) ;
istringstream
int n;
i s s ( argv [ 1 ] ) ;
i s s >> n ;
if
(! iss )
throw i n v a l i d a r g u m e n t ( ” e l p a r a m e t r o no e s un numero
valido ”) ;
r e t u r n EXIT SUCCESS ;
}
c o u t << a r g v [ 0 ] << ” ( ” << a r g v [ 1 ] << ” ) = ” << f i b ( n ) <<
endl ;
}
c a t c h ( e x c e p t i o n& e )
{
c e r r << a r g v [ 0 ] << ” : ” << e . what ( ) << e n d l ;
r e t u r n EXIT FAILURE ;
}
c Gustavo Romero
Práctica 4 (11/12)
c Gustavo Romero
Práctica 4 (12/12)