00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
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
00048
00049
00050 #ifdef PERFMON
00051 #if defined (__i386__)
00052 #include <libperfctr.h>
00053 #define PERF1_CODE p6_events[P6_DCU_MISS_OUTSTANDING]
00054
00055 #define PERF2_CODE p6_events[P6_RESOURCE_STALLS]
00056
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
00065 #error PERMON only supported on x86
00066
00067
00068
00069 #endif //x86
00070
00071
00072
00073
00074
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
00092 public:
00093
00094
00095
00096 unsigned long long skippedData;
00097
00098
00099
00100 unsigned long long bufferFullOnWrite;
00101
00102
00103
00104
00105
00106
00107
00108 unsigned long long WPdelayedUpdate;
00109
00110
00111
00112 unsigned long long blockOnUnmarkedData;
00113
00114
00115 unsigned long long uncompleteWork;
00116
00117
00118
00119
00120
00121
00122
00123 unsigned long long blockOnMarkedData;
00124
00125
00126 unsigned long long blockOnSync;
00127
00128 public:
00129
00130 void startCount() {
00131
00132 #ifdef THREADS
00133 pmcs *p=(pmcs *) pthread_getspecific(mystart);
00134 if(p == 0) {
00135
00136 p=new pmcs;
00137 pthread_setspecific(mystart,(void *) p);
00138
00139 if (0){
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