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)
© Copyright 2024