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