Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

VrCycleCount.h

Go to the documentation of this file.
00001 /* -*- Mode: c++ -*- */ 00002 /* 00003 * Copyright 2001 Free Software Foundation, Inc. 00004 * 00005 * This file is part of GNU Radio 00006 * 00007 * GNU Radio is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2, or (at your option) 00010 * any later version. 00011 * 00012 * GNU Radio is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with GNU Radio; see the file COPYING. If not, write to 00019 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00020 * Boston, MA 02111-1307, USA. 00021 */ 00022 /* 00023 * Copyright 1997 Massachusetts Institute of Technology 00024 * 00025 * Permission to use, copy, modify, distribute, and sell this software and its 00026 * documentation for any purpose is hereby granted without fee, provided that 00027 * the above copyright notice appear in all copies and that both that 00028 * copyright notice and this permission notice appear in supporting 00029 * documentation, and that the name of M.I.T. not be used in advertising or 00030 * publicity pertaining to distribution of the software without specific, 00031 * written prior permission. M.I.T. makes no representations about the 00032 * suitability of this software for any purpose. It is provided "as is" 00033 * without express or implied warranty. 00034 * 00035 */ 00036 00037 #ifndef _VRCYCLECOUNT_H_ 00038 #define _VRCYCLECOUNT_H_ 00039 00040 extern "C" { 00041 #include <stdio.h> 00042 #ifdef THREADS 00043 #include<pthread.h> 00044 #endif 00045 } 00046 00047 //brettv 6/24/99 I junked the old user-level perfmon stuff. 00048 //PERMON now requires the kernel driver to operation 00049 00050 #ifdef PERFMON 00051 #if defined (__i386__) 00052 #include <libperfctr.h> 00053 #define PERF1_CODE p6_events[P6_DCU_MISS_OUTSTANDING] 00054 //#define PERF0_NAME "DCU miss cycles" 00055 #define PERF2_CODE p6_events[P6_RESOURCE_STALLS] 00056 //#define PERF1_NAME "Resource stalls" 00057 00058 #define PERF1_NAME PERF1_CODE.desc 00059 #define PERF2_NAME PERF2_CODE.desc 00060 00061 #define START_COUNTS() start_counters(PERF1_CODE.id,PERF2_CODE.id) 00062 #define STOP_COUNTS() perfctr_disable() 00063 #else 00064 //not supported 00065 #error PERMON only supported on x86 00066 /*alpha #define CYCLE_COUNT() ({ volatile unsigned long time; \ 00067 __asm__("rpcc %0" :"=r" (time)); \ 00068 (unsigned long)((time >> 32) + (time & 0x00000000ffffffff)); })*/ 00069 #endif //x86 00070 00071 //Global counts: 00072 //------------- 00073 00074 //Per module counts: 00075 //----------------- 00076 typedef struct { 00077 unsigned long long counter[3]; 00078 } pmcs; 00079 00080 class VrCycleCount { 00081 private: 00082 long totalSamples; 00083 pmcs total; 00084 00085 #ifdef THREADS 00086 pthread_key_t mystart; 00087 pthread_mutex_t mutex; 00088 #else 00089 pmcs start; 00090 #endif 00091 //*** the rest of this stuff is Pspectra internal performance stuff 00092 public: 00093 //By occurrence: 00094 //-------------- 00095 //no one computed the data ahead of mine, and I can skip it 00096 unsigned long long skippedData; //number of units skipped 00097 00098 //couldn't mark data because there wasn't enough room in the downstream 00099 //buffer 00100 unsigned long long bufferFullOnWrite; //# of occurrences 00101 00102 //data is computed (ready) but other threads won't know 00103 // because we're using an oversimplified linked list. 00104 //(i.e. out of order completion of writing threads.) 00105 //if both this and blockOnMarkedData are high 00106 //more work should be done here to fix our writeLL data 00107 //structure 00108 unsigned long long WPdelayedUpdate; //#occurrences 00109 00110 //no one has marked the data ahead of mine yet so I have to wait! 00111 //(i.e. I couldnt' skip data) 00112 unsigned long long blockOnUnmarkedData; //#occurrences 00113 00114 //# of times work() didn't finish all its work 00115 unsigned long long uncompleteWork; //#occurrences 00116 00117 //By duration: 00118 //-------------- 00119 //cycles are kind of bogus right now -- should use perfctr stuff 00120 //FIX 00121 00122 //the previous thread didn't finish data I need! 00123 unsigned long long blockOnMarkedData; //#cycles spent waiting 00124 00125 //blocked in sync() 00126 unsigned long long blockOnSync; //#cycles spent waiting 00127 00128 public: 00129 /*** Performance monitoring procedures ***/ 00130 void startCount() { 00131 00132 #ifdef THREADS 00133 pmcs *p=(pmcs *) pthread_getspecific(mystart); 00134 if(p == 0) { 00135 //init thread specific data 00136 p=new pmcs; 00137 pthread_setspecific(mystart,(void *) p); 00138 00139 if (0){ // FIXME -eb 00140 pthread_mutex_lock(&mutex); 00141 if(START_COUNTS()<0) { 00142 perror("VrCycleCount: could not start counts"); 00143 fprintf(stderr,"Must be running on a system with the /dev/perfctr driver installed.\n"); 00144 exit(-1); 00145 } 00146 pthread_mutex_unlock(&mutex); 00147 } 00148 00149 } 00150 else if (PARANOID && p->counter[0]!=0) { 00151 fprintf(stderr, "VrCycleCount(%p): counter already started! \n", this); 00152 abort (); 00153 } 00154 00155 #else 00156 00157 pmcs *p = &start; 00158 if(PARANOID && start.counter[0]) { 00159 fprintf(stderr, "VrCycleCount(%p): counter already started! \n", this); 00160 abort (); 00161 } 00162 00163 #endif 00164 00165 struct perfctr_state state; 00166 if( perfctr_read(&state) < 0 ) { 00167 perror("perfctr_read"); 00168 exit(1); 00169 } 00170 p->counter[0] = state.counters.tsc.u64; 00171 p->counter[1] = state.counters.pmc[0].u64; 00172 p->counter[2] = state.counters.pmc[1].u64; 00173 } 00174 00175 void stopCount() { 00176 #ifdef THREADS 00177 pmcs *p=(pmcs *) pthread_getspecific(mystart); 00178 if(PARANOID && (p == 0 || !p->counter[0])) { 00179 fprintf(stderr, "VrCycleCount(%p): counter not running! \n", this); 00180 exit(-1); 00181 } 00182 #else 00183 pmcs *p = &start; 00184 if(PARANOID && !start.counter[0]) { 00185 fprintf(stderr, "VrCycleCount: counter not running! \n"); 00186 exit(-1); 00187 } 00188 #endif 00189 00190 struct perfctr_state state; 00191 if (perfctr_read(&state) < 0 ) { 00192 perror("perfctr_read"); 00193 exit(1); 00194 } 00195 00196 MUTEX_LOCK(&mutex); 00197 00198 if (PARANOID){ 00199 if(state.counters.tsc.u64 < p->counter[0] || 00200 state.counters.pmc[0].u64 < p->counter[1] || 00201 state.counters.pmc[1].u64 < p->counter[2]) { 00202 fprintf(stderr, "Counters running backwards!\n"); 00203 abort (); 00204 } 00205 } 00206 00207 total.counter[0] += (state.counters.tsc.u64 - p->counter[0]); 00208 total.counter[1] += (state.counters.pmc[0].u64 - p->counter[1]); 00209 total.counter[2] += (state.counters.pmc[1].u64 - p->counter[2]); 00210 00211 MUTEX_UNLOCK(&mutex); 00212 00213 #ifdef THREADS 00214 p->counter[0]=0; 00215 #else 00216 start.counter[0] = 0; 00217 #endif 00218 } 00219 00220 void resetCount() { 00221 for(int i=0;i<3;i++) { 00222 total.counter[i]=0; 00223 } 00224 skippedData = bufferFullOnWrite = WPdelayedUpdate = 00225 blockOnUnmarkedData = uncompleteWork = 00226 blockOnMarkedData = blockOnSync = 0; 00227 } 00228 00229 long long getTotalCycles() {return total.counter[0];} 00230 00231 long long getTotalCycles(int measure) { 00232 if(measure < 3) 00233 return total.counter[measure]; 00234 else 00235 return 0; 00236 } 00237 00238 static char *measurementName(int n) { 00239 switch(n) { 00240 case 0: 00241 return "cycles"; 00242 case 1: 00243 return PERF1_NAME; 00244 case 2: 00245 return PERF2_NAME; 00246 default: 00247 return NULL; 00248 } 00249 } 00250 00251 void updateSamples(int n) {totalSamples += n;} 00252 long getTotalSamples() {return totalSamples;} 00253 00254 void print_stats(); 00255 VrCycleCount(); 00256 }; 00257 00258 #endif //PERFMON 00259 #endif

Generated on Wed Aug 4 02:22:05 2004 for GNU Radio by doxygen 1.3.8