From e61537d93e3a5298215cb9970b091a94998374e1 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 8 Sep 2011 15:14:10 +0200 Subject: [PATCH] Get the time spent in busy-wait per stream. --- libgomp/stream.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++- libgomp/stream.h | 8 ++++ 2 files changed, 125 insertions(+), 2 deletions(-) diff --git a/libgomp/stream.c b/libgomp/stream.c index 0269e62f3..0e8dc5ad6 100644 --- a/libgomp/stream.c +++ b/libgomp/stream.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "wait.h" #include "sem.h" @@ -130,6 +131,11 @@ GOMP_stream_create_stream (size_t element_size, size_t buffer_size) stream->write_views.nr_expected_views = 0; stream->write_views.nr_registered_views = 0; stream->write_views.nr_unregistered_views = 0; + + stream->tvr.tv_sec = 0; + stream->tvr.tv_usec = 0; + stream->tvw.tv_sec = 0; + stream->tvw.tv_usec = 0; gomp_mutex_init (&stream->write_views.view_list.connect_view_mutex); #ifndef HAVE_SYNC_BUILTINS @@ -214,6 +220,10 @@ GOMP_batchQ_create_stream (size_t element_size, size_t buffer_size) stream->pre_shift = 0; + stream->tvr.tv_sec = 0; + stream->tvr.tv_usec = 0; + stream->tvw.tv_sec = 0; + stream->tvw.tv_usec = 0; close_file: shm_unlink(shm_name); @@ -686,7 +696,28 @@ GOMP_stream_update (void *v, const unsigned long long act_start, yet higher index, then there is no need to check for this one. */ if (up_idx > view->stream->read_views.current_max) { + struct timeval tv1, tv2; + time_t sec; + unsigned int usec; + + gettimeofday(&tv1, NULL); + gomp_stream_wait_release (view, &view->stream->write_views, up_idx); + + gettimeofday(&tv2, NULL); + if (tv2.tv_usec < tv1.tv_usec) + { + sec = tv2.tv_sec - tv1.tv_sec - 1; + usec = 1000000 + tv2.tv_usec - tv1.tv_usec; + } + else + { + sec = tv2.tv_sec - tv1.tv_sec; + usec = tv2.tv_usec - tv1.tv_usec; + } + stream->tvr.tv_usec = (stream->tvr.tv_usec + usec) % 1000000; + stream->tvr.tv_sec += sec + ((stream->tvr.tv_usec + usec) / 1000000); + view->stream->read_views.current_max = up_idx; } @@ -740,7 +771,31 @@ GOMP_batchQ_update (void *v, const unsigned long long act_start, } #endif - while (!stream->state); + if (!stream->state) + { + struct timeval tv1, tv2; + time_t sec; + unsigned int usec; + + gettimeofday(&tv1, NULL); + + while (!stream->state) + sched_yield(); + + gettimeofday(&tv2, NULL); + if (tv2.tv_usec < tv1.tv_usec) + { + sec = tv2.tv_sec - tv1.tv_sec - 1; + usec = 1000000 + tv2.tv_usec - tv1.tv_usec; + } + else + { + sec = tv2.tv_sec - tv1.tv_sec; + usec = tv2.tv_usec - tv1.tv_usec; + } + stream->tvr.tv_usec = (stream->tvr.tv_usec + usec) % 1000000; + stream->tvr.tv_sec += sec + ((stream->tvr.tv_usec + usec) / 1000000); + } return (void *) stream->receiver_ptr; } @@ -776,7 +831,28 @@ GOMP_stream_stall (void *v, const unsigned long long act_start, if (up_idx > stream->write_views.current_max) { + struct timeval tv1, tv2; + time_t sec; + unsigned int usec; + + gettimeofday(&tv1, NULL); + gomp_stream_wait_release (view, &stream->read_views, up_idx); + + gettimeofday(&tv2, NULL); + if (tv2.tv_usec < tv1.tv_usec) + { + sec = tv2.tv_sec - tv1.tv_sec - 1; + usec = 1000000 + tv2.tv_usec - tv1.tv_usec; + } + else + { + sec = tv2.tv_sec - tv1.tv_sec; + usec = tv2.tv_usec - tv1.tv_usec; + } + stream->tvw.tv_usec = (stream->tvw.tv_usec + usec) % 1000000; + stream->tvw.tv_sec += sec + ((stream->tvw.tv_usec + usec) / 1000000); + stream->write_views.current_max = up_idx; } @@ -885,7 +961,32 @@ GOMP_batchQ_commit (void *v, const unsigned long long act_idx) gomp_batchQ_view_p view = (gomp_batchQ_view_p) v; gomp_batchQ_p stream = view->stream; - while (stream->state); + if (stream->state) + { + struct timeval tv1, tv2; + time_t sec; + unsigned int usec; + + gettimeofday(&tv1, NULL); + + while (stream->state) + sched_yield(); + + gettimeofday(&tv2, NULL); + if (tv2.tv_usec < tv1.tv_usec) + { + sec = tv2.tv_sec - tv1.tv_sec - 1; + usec = 1000000 + tv2.tv_usec - tv1.tv_usec; + } + else + { + sec = tv2.tv_sec - tv1.tv_sec; + usec = tv2.tv_usec - tv1.tv_usec; + } + stream->tvw.tv_usec = (stream->tvw.tv_usec + usec) % 1000000; + stream->tvw.tv_sec += sec + ((stream->tvw.tv_usec + usec) / 1000000); + } + stream->state = 1; if (stream->sender_buf == stream->buf_start1) { @@ -947,6 +1048,12 @@ gomp_stream_unregister_view (gomp_stream_view_p view) free (stream->buffer); free (read_view_list->views); free (write_view_list->views); + printf("GOMP stream %p spinned for %jd secs %jd usecs on output\n", + stream, (uintmax_t) stream->tvr.tv_sec, + (uintmax_t) stream->tvr.tv_usec); + printf("GOMP stream %p spinned for %jd secs %jd usecs on input\n", + stream, (uintmax_t) stream->tvw.tv_sec, + (uintmax_t) stream->tvw.tv_usec); free (stream); } } @@ -955,6 +1062,14 @@ gomp_stream_unregister_view (gomp_stream_view_p view) static inline void gomp_batchQ_unregister_view (gomp_stream_view_p view) { + gomp_batchQ_p stream = ((gomp_batchQ_view_p) view)->stream; + + printf("BatchQueue stream %p spinned for %jd secs %jd usecs on output\n", + stream, (uintmax_t) stream->tvr.tv_sec, + (uintmax_t) stream->tvr.tv_usec); + printf("BatchQueue stream %p spinned for %jd secs %jd usecs on input\n", + stream, (uintmax_t) stream->tvw.tv_sec, + (uintmax_t) stream->tvw.tv_usec); } /* Invoked before terminating a stream TASK, this disconnects all the diff --git a/libgomp/stream.h b/libgomp/stream.h index f901d41fc..b7c2a6f4e 100644 --- a/libgomp/stream.h +++ b/libgomp/stream.h @@ -185,6 +185,10 @@ typedef struct gomp_stream unsigned long long buffer_mask; unsigned long long pre_shift; + /* Time elapsed waiting on production Vs consumption */ + struct timeval tvr; + struct timeval tvw; + /* True once all the tasks that should be expected to connect to this stream been declared. */ bool expected_ready_p; @@ -229,6 +233,10 @@ typedef struct gomp_batchQ size_t pre_shift; volatile unsigned int state:1; + /* Time elapsed waiting on production Vs consumption */ + struct timeval tvr; + struct timeval tvw; + char volatile *sender_ptr __attribute__ ((aligned (CACHE_LINE_SIZE))); char volatile *sender_buf; /* Which buffer is sender using? */ char volatile *receiver_ptr __attribute__ ((aligned (CACHE_LINE_SIZE)));