From 8044adb1356b8a86cf259a64adaccd4e20d882a1 Mon Sep 17 00:00:00 2001 From: Pedro Gonnet <pedro.gonnet@durham.ac.uk> Date: Fri, 1 Nov 2013 08:54:22 +0000 Subject: [PATCH] added timers. --- src/Makefile.am | 2 +- src/Makefile.in | 2 +- src/qsched.c | 78 +++++++++++++++++++++++++++++++++++++++---------- src/qsched.h | 29 ++++++++++++++++++ 4 files changed, 94 insertions(+), 17 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 791e647..d8b11d7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,7 +20,7 @@ AUTOMAKE_OPTIONS=gnu # Add the debug flag to the whole thing AM_CFLAGS = -g -O3 -Wall -Werror -ffast-math -fstrict-aliasing -ftree-vectorize \ - -funroll-loops $(SIMD_FLAGS) $(OPENMP_CFLAGS) \ + -funroll-loops $(SIMD_FLAGS) $(OPENMP_CFLAGS) -DTIMERS \ -fsanitize=address -fno-omit-frame-pointer # Assign a "safe" version number diff --git a/src/Makefile.in b/src/Makefile.in index 1869026..d0b2f08 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -296,7 +296,7 @@ AUTOMAKE_OPTIONS = gnu # Add the debug flag to the whole thing AM_CFLAGS = -g -O3 -Wall -Werror -ffast-math -fstrict-aliasing -ftree-vectorize \ - -funroll-loops $(SIMD_FLAGS) $(OPENMP_CFLAGS) \ + -funroll-loops $(SIMD_FLAGS) $(OPENMP_CFLAGS) -DTIMERS \ -fsanitize=address -fno-omit-frame-pointer diff --git a/src/qsched.c b/src/qsched.c index 27d3db8..8ec3e8f 100644 --- a/src/qsched.c +++ b/src/qsched.c @@ -46,6 +46,11 @@ #include "queue.h" +/** Timer names. */ +char *qsched_timer_names[ qsched_timer_count ] = + { "queue" , "lock" , "gettask" , "done" , "prepare" }; + + /** * @brief Change the owner of a resource. * @@ -263,6 +268,11 @@ void qsched_reset ( struct qsched *s ) { s->count_uses = 0; s->count_res = 0; + /* Clear the timers. */ + #ifdef TIMERS + bzero( s->timers , sizeof(ticks) * qsched_timer_count ); + #endif + } @@ -486,6 +496,8 @@ void qsched_done ( struct qsched *s , struct task *t ) { int k; struct task *t2; + + TIMER_TIC /* Release this task's locks. */ for ( k = 0 ; k < t->nr_locks ; k++ ) @@ -518,6 +530,10 @@ void qsched_done ( struct qsched *s , struct task *t ) { pthread_mutex_unlock( &s->mutex ); } #endif + + /* Careful, this may pick up duplicate timers if virtual + tasks are used. */ + TIMER_TOC( s , qsched_timer_done ) } @@ -610,6 +626,8 @@ int qsched_locktask ( struct qsched *s , int tid ) { int k; struct task *t; + + TIMER_TIC /* Get a pointer on the task. */ t = &s->tasks[tid]; @@ -627,13 +645,16 @@ int qsched_locktask ( struct qsched *s , int tid ) { qsched_unlockres( s , t->locks[k] ); /* Fail. */ + TIMER_TOC( s , qsched_timer_lock ) return 0; } /* Otherwise, all went well. */ - else + else { + TIMER_TOC( s , qsched_timer_lock ) return 1; + } } @@ -649,6 +670,8 @@ void qsched_unlocktask ( struct qsched *s , int tid ) { int k; struct task *t; + + TIMER_TIC /* Get a pointer on the task. */ t = &s->tasks[tid]; @@ -656,6 +679,8 @@ void qsched_unlocktask ( struct qsched *s , int tid ) { /* Unlock the used resources. */ for ( k = 0 ; k < t->nr_locks ; k++ ) qsched_unlockres( s , t->locks[k] ); + + TIMER_TOC( s , qsched_timer_lock ) } @@ -677,6 +702,8 @@ struct task *qsched_gettask ( struct qsched *s , int qid ) { int naq, k, tid, qids[ s->nr_queues ]; struct task *t; + + TIMER_TIC /* Check if the sched is ok. */ if ( s->flags & qsched_flag_dirty || !(s->flags & qsched_flag_ready) ) @@ -690,20 +717,28 @@ struct task *qsched_gettask ( struct qsched *s , int qid ) { while ( s->waiting ) { /* Try to get a task from my own queue. */ - if ( ( tid = queue_get( &s->queues[qid] , s ) ) < 0 ) { - - /* Otherwise, hit the other queues. */ - for ( naq = 0 , k = 0 ; k < s->nr_queues ; k++ ) - if ( k != qid && s->queues[k].count > 0 ) - qids[ naq++ ] = k; - while ( naq > 0 ) { - k = rand() % naq; - if ( ( tid = queue_get( &s->queues[ qids[k] ] , s ) ) < 0 ) - qids[k] = qids[ --naq ]; - else - break; + { + TIMER_TIC + tid = queue_get( &s->queues[qid] , s ); + TIMER_TOC( s , qsched_timer_queue ) + if ( tid < 0 ) { + + /* Otherwise, hit the other queues. */ + for ( naq = 0 , k = 0 ; k < s->nr_queues ; k++ ) + if ( k != qid && s->queues[k].count > 0 ) + qids[ naq++ ] = k; + while ( naq > 0 ) { + k = rand() % naq; + TIMER_TIC2 + tid = queue_get( &s->queues[ qids[k] ] , s ); + TIMER_TOC( s , qsched_timer_queue ) + if ( tid < 0 ) + qids[k] = qids[ --naq ]; + else + break; + } + } - } /* Bail if a valid task ID was returned. */ @@ -725,6 +760,7 @@ struct task *qsched_gettask ( struct qsched *s , int qid ) { t->qid = qid; /* Return the task. */ + TIMER_TOC( s , qsched_timer_gettask ) return t; } @@ -732,16 +768,19 @@ struct task *qsched_gettask ( struct qsched *s , int qid ) { /* Otherwise, take a nap? */ #ifdef HAVE_PTHREAD else if ( s->flags & qsched_flag_yield ) { + TIMER_TOC( s , qsched_timer_gettask ) pthread_mutex_lock( &s->mutex ); if ( s->waiting ) pthread_cond_wait( &s->cond , &s->mutex ); pthread_mutex_unlock( &s->mutex ); + TIMER_TIC2 } #endif } - /* Return empty-handed. */ + /* Return empty-handed. No toc here as we don't want to + count the final wait when all tasks have been executed. */ return NULL; } @@ -840,6 +879,8 @@ void qsched_prepare ( struct qsched *s ) { int j, k, count; struct task *t, *tasks; + + TIMER_TIC /* Lock the sched. */ lock_lock( &s->lock ); @@ -946,6 +987,8 @@ void qsched_prepare ( struct qsched *s ) { /* Unlock the sched. */ lock_unlock_blind( &s->lock ); + + TIMER_TOC( s , qsched_timer_prepare ) } @@ -1384,6 +1427,11 @@ void qsched_init ( struct qsched *s , int nr_queues , int flags ) { error( "Error initializing cond/mutex pair." ); #endif + /* Clear the timers. */ + #ifdef TIMERS + bzero( s->timers , sizeof(ticks) * qsched_timer_count ); + #endif + /* Init the sched lock. */ lock_init( &s->lock ); diff --git a/src/qsched.h b/src/qsched.h index 5a98750..0bc52cd 100644 --- a/src/qsched.h +++ b/src/qsched.h @@ -51,6 +51,30 @@ typedef int qsched_res_t; typedef void (*qsched_funtype)( int , void * ); +/** Timer types. */ +enum qsched_timer { + qsched_timer_queue = 0, + qsched_timer_lock, + qsched_timer_gettask, + qsched_timer_done, + qsched_timer_prepare, + qsched_timer_count + }; +extern char *qsched_timer_names[]; + + +/* Timer macros. */ +#ifdef TIMERS + #define TIMER_TIC ticks __tic = getticks(); + #define TIMER_TIC2 __tic = getticks(); + #define TIMER_TOC(s,tid) atomic_add( &s->timers[tid] , getticks() - __tic ); +#else + #define TIMER_TIC + #define TIMER_TIC2 + #define TIMER_TOC +#endif + + /* The sched data structre. */ struct qsched { @@ -128,6 +152,11 @@ struct qsched { pthread_mutex_t mutex; #endif + /* Timers. */ + #ifdef TIMERS + ticks timers[ qsched_timer_count ]; + #endif + }; -- GitLab