Mercurial > cgi-bin > hgwebdir.cgi > PR > Applications > Vthread > Vthread__Best_Effort_Msg__Bench
changeset 4:e512fcf3748e
Initial add
| author | Me@portablequad |
|---|---|
| date | Sat, 22 Oct 2011 19:27:29 -0700 |
| parents | 80a90f221047 |
| children | 535c119ba090 |
| files | src/Application/main.c |
| diffstat | 1 files changed, 256 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/Application/main.c Sat Oct 22 19:27:29 2011 -0700 1.3 @@ -0,0 +1,256 @@ 1.4 +/* 1.5 + * 1.6 + */ 1.7 +#include <stdio.h> 1.8 +#include <stdlib.h> 1.9 +#include <string.h> 1.10 +#include <math.h> 1.11 +#include <ctype.h> 1.12 +#include <errno.h> 1.13 +#include <pthread.h> 1.14 +#include "VPThread_lib/VPThread.h" 1.15 +#include "VPThread_lib/VMS/Queue_impl/PrivateQueue.h" 1.16 + 1.17 +#undef DEBUG 1.18 +//#define DEBUG 1.19 + 1.20 +#if !defined(unix) && !defined(__unix__) 1.21 +#ifdef __MACH__ 1.22 +#define unix 1 1.23 +#define __unix__ 1 1.24 +#endif /* __MACH__ */ 1.25 +#endif /* unix */ 1.26 + 1.27 +/* find the appropriate way to define explicitly sized types */ 1.28 +/* for C99 or GNU libc (also mach's libc) we can use stdint.h */ 1.29 +#if (__STDC_VERSION__ >= 199900) || defined(__GLIBC__) || defined(__MACH__) 1.30 +#include <stdint.h> 1.31 +#elif defined(unix) || defined(__unix__) /* some UNIX systems have them in sys/types.h */ 1.32 +#include <sys/types.h> 1.33 +#elif defined(__WIN32__) || defined(WIN32) /* the nameless one */ 1.34 +typedef unsigned __int8 uint8_t; 1.35 +typedef unsigned __int32 uint32_t; 1.36 +#endif /* sized type detection */ 1.37 + 1.38 +/* provide a millisecond-resolution timer for each system */ 1.39 +#if defined(unix) || defined(__unix__) 1.40 +#include <time.h> 1.41 +#include <sys/time.h> 1.42 +unsigned long get_msec(void) { 1.43 + static struct timeval timeval, first_timeval; 1.44 + 1.45 + gettimeofday(&timeval, 0); 1.46 + if(first_timeval.tv_sec == 0) { 1.47 + first_timeval = timeval; 1.48 + return 0; 1.49 + } 1.50 + return (timeval.tv_sec - first_timeval.tv_sec) * 1000 + (timeval.tv_usec - first_timeval.tv_usec) / 1000; 1.51 +} 1.52 +#elif defined(__WIN32__) || defined(WIN32) 1.53 +#include <windows.h> 1.54 +unsigned long get_msec(void) { 1.55 + return GetTickCount(); 1.56 +} 1.57 +#else 1.58 +//#error "I don't know how to measure time on your platform" 1.59 +#endif 1.60 + 1.61 +//======================== Defines ========================= 1.62 + 1.63 +const char *usage = { 1.64 + "Usage: malloc_test [options]\n" 1.65 + " Spwans a number of threads and allocates memory.\n\n" 1.66 + "Options:\n" 1.67 + " -t <num> how many threads to use (default: 1)\n" 1.68 + " -m <num> repeat workload and sync operation <m> times\n" 1.69 + " -n <num> size of workload, repeat <n> times\n" 1.70 + " -h this help screen\n\n" 1.71 +}; 1.72 + 1.73 +struct barrier_t 1.74 +{ 1.75 + int counter; 1.76 + int nthreads; 1.77 + int32 mutex; 1.78 + int32 cond; 1.79 +}; 1.80 +typedef struct barrier_t barrier; 1.81 + 1.82 +void inline barrier_init(barrier *barr, int nthreads, VirtProcr *animatingPr) 1.83 + { 1.84 + barr->counter = 0; 1.85 + barr->nthreads = nthreads; 1.86 + barr->mutex = VPThread__make_mutex(animatingPr); 1.87 + barr->cond = VPThread__make_cond(barr->mutex, animatingPr); 1.88 + } 1.89 + 1.90 +void inline barrier_wait(barrier *barr, VirtProcr *animatingPr) 1.91 + { int i; 1.92 + 1.93 + VPThread__mutex_lock(barr->mutex, animatingPr); 1.94 + barr->counter++; 1.95 + if(barr->counter == barr->nthreads) 1.96 + { barr->counter = 0; 1.97 + for(i=0; i < barr->nthreads; i++) 1.98 + VPThread__cond_signal(barr->cond, animatingPr); 1.99 + } 1.100 + else 1.101 + { VPThread__cond_wait(barr->cond, animatingPr); 1.102 + } 1.103 + VPThread__mutex_unlock(barr->mutex, animatingPr); 1.104 + } 1.105 + 1.106 + 1.107 + 1.108 +union workload{ 1.109 + uint32 highLow[2]; 1.110 + uint64 total; 1.111 +}; 1.112 + 1.113 +struct input_t{ 1.114 + struct barrier_t* barrier; 1.115 + uint64 workcycles; 1.116 +}; 1.117 + 1.118 + 1.119 +//======================== Globals ========================= 1.120 +char __ProgrammName[] = "overhead_test"; 1.121 +char __DataSet[255]; 1.122 + 1.123 +int repetitions, workload_size, num_threads; 1.124 +size_t chunk_size = 0; 1.125 + 1.126 + 1.127 +//======================== App Code ========================= 1.128 +/* 1.129 + * Workload 1.130 + */ 1.131 +void work(void* input, VirtProcr* animatingPr) 1.132 +{ 1.133 + int n,m; 1.134 + struct input_t* in = (struct input_t*)input; 1.135 + unsigned int totalCycles = 0; 1.136 + unsigned int workspace1; 1.137 + double workspace2; 1.138 + int32 privateMutex = VPThread__make_mutex(animatingPr); 1.139 + 1.140 + for(m=0; m<repetitions; m++) 1.141 + { 1.142 + int32 stamp_startWorkload, stamp_endWorkload; 1.143 + saveLowTimeStampCountInto( stamp_startWorkload ); 1.144 + for(n=0; n<workload_size; n++) 1.145 + { 1.146 + workspace1 += (workspace1 + 32)/2; 1.147 + workspace2 += (workspace2 + 23.2)/1.4; 1.148 + } 1.149 + saveLowTimeStampCountInto( stamp_endWorkload ); 1.150 + int32 numCycles = stamp_endWorkload-stamp_startWorkload; 1.151 + if( numCycles < 100000000 ) totalCycles += numCycles; //sanity check 1.152 + 1.153 + VPThread__mutex_lock(privateMutex, animatingPr); 1.154 + //access queue 1.155 + VPThread__mutex_unlock(privateMutex, animatingPr); 1.156 + } 1.157 + 1.158 + in->workcycles = totalCycles; 1.159 + barrier_wait(in->barrier,animatingPr); 1.160 + //Shutdown worker 1.161 + VPThread__dissipate_thread(animatingPr); 1.162 + printf("%d", workspace1); 1.163 + printf("%f", workspace2); 1.164 +} 1.165 + 1.166 +/* this is run after the VMS is set up*/ 1.167 +void benchmark(void *in, VirtProcr *animatingPr) 1.168 + { 1.169 + int i; 1.170 + struct input_t input[num_threads]; 1.171 + struct barrier_t barr; 1.172 + barrier_init(&barr, num_threads+1, animatingPr); 1.173 + 1.174 + for(i=0; i<num_threads; i++) 1.175 + { input[i].barrier = &barr; 1.176 + } 1.177 + 1.178 + union workload stamp_startThread, stamp_endThread; 1.179 + saveTimeStampCountInto(stamp_startThread.highLow[0], stamp_startThread.highLow[1]); 1.180 + for(i=0; i<num_threads; i++) 1.181 + { VPThread__create_thread((VirtProcrFnPtr)work, (void*)&input[i], animatingPr); 1.182 + } 1.183 + barrier_wait(&barr, animatingPr); 1.184 + saveTimeStampCountInto(stamp_endThread.highLow[0], stamp_endThread.highLow[1]); 1.185 + 1.186 + 1.187 + for(i=0; i<num_threads; i++) 1.188 + { printf("Workcycles: %d\n",input[i].workcycles); 1.189 + } 1.190 + printf("Total cycles %lu\n", stamp_endThread.total-stamp_startThread.total); 1.191 + 1.192 + //====================================================== 1.193 + 1.194 + VPThread__dissipate_thread(animatingPr); 1.195 + } 1.196 + 1.197 +int main(int argc, char **argv) 1.198 + { 1.199 + int i; 1.200 + 1.201 + //set global static variables, based on cmd-line args 1.202 + for(i=1; i<argc; i++) 1.203 + { 1.204 + if(argv[i][0] == '-' && argv[i][2] == 0) 1.205 + { 1.206 + switch(argv[i][1]) 1.207 + { 1.208 + case 't': 1.209 + if(!isdigit(argv[++i][0])) 1.210 + { 1.211 + fprintf(stderr, "-t mus be followed by the number of worker threads to spawn\n"); 1.212 + return EXIT_FAILURE; 1.213 + } 1.214 + num_threads = atoi(argv[i]); 1.215 + if(!num_threads) 1.216 + { 1.217 + fprintf(stderr, "invalid number of threads specified: %d\n", num_threads); 1.218 + return EXIT_FAILURE; 1.219 + } 1.220 + break; 1.221 + case 'n': 1.222 + if(!isdigit(argv[++i][0])) 1.223 + { 1.224 + fputs("-n must be followed by a number\n", stderr); 1.225 + return EXIT_FAILURE; 1.226 + } 1.227 + repetitions = atoi(argv[i]); 1.228 + break; 1.229 + case 'm': 1.230 + if(!isdigit(argv[++i][0])) 1.231 + { 1.232 + fputs("-m must be followed by a number (workload size)\n", stderr); 1.233 + return EXIT_FAILURE; 1.234 + } 1.235 + workload_size = atoi(argv[i]); 1.236 + break; 1.237 + case 'h': 1.238 + fputs(usage, stdout); 1.239 + return 0; 1.240 + 1.241 + default: 1.242 + fprintf(stderr, "unrecognized argument: %s\n", argv[i]); 1.243 + fputs(usage, stderr); 1.244 + return EXIT_FAILURE; 1.245 + }//switch 1.246 + }//if arg 1.247 + else 1.248 + { 1.249 + fprintf(stderr, "unrecognized argument: %s\n", argv[i]); 1.250 + fputs(usage, stderr); 1.251 + return EXIT_FAILURE; 1.252 + } 1.253 + }//for 1.254 + 1.255 + //This is the transition to the VMS runtime 1.256 + VPThread__create_seed_procr_and_do_work(benchmark, NULL); 1.257 + 1.258 + return 0; 1.259 +}
