Gaudi Framework, version v23r7
Home
Generated: Wed Mar 20 2013
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
GaudiProfiling
GaudiProfiling
PfmCodeAnalyser.h
Go to the documentation of this file.
1
#ifndef PfmCodeAnalyserH
2
#define PfmCodeAnalyserH 1
3
4
#include <
stdlib.h
>
5
#include <
stdio.h
>
6
#include <
perfmon/pfmlib.h
>
7
#include <
perfmon/perfmon.h
>
8
#include <
perfmon/perfmon_dfl_smpl.h
>
9
#include <
perfmon/pfmlib_core.h
>
10
#include <
perfmon/pfmlib_intel_nhm.h
>
11
#include <string.h>
12
#include <sys/types.h>
13
#include <unistd.h>
14
15
#define MAX_EVT_NAME_LEN 256
16
#define NUM_PMCS PFMLIB_MAX_PMCS
17
#define NUM_PMDS PFMLIB_MAX_PMDS
18
#define FMT_NAME PFM_DFL_SMPL_NAME
19
#define MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS 4
20
#define cpuid(func,eax,ebx,ecx,edx) __asm__ __volatile__ ("cpuid": "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (func));
21
22
class
PfmCodeAnalyser
23
{
24
private
:
25
int
used_counters_number
;
26
int
nehalem
;
27
pfmlib_input_param_t
inp
;
28
pfmlib_output_param_t
outp
;
29
pfarg_ctx_t
ctx
;
30
pfarg_pmd_t
pd
[
NUM_PMDS
];
31
pfarg_pmc_t
pc
[
NUM_PMCS
];
32
pfarg_load_t
load_arg
;
33
int
fd
;
34
char
event_str
[
MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS
][
MAX_EVT_NAME_LEN
];
35
bool
inv
[
MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS
];
36
unsigned
int
cmask
[
MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS
];
37
pfmlib_core_input_param_t
params
;
38
pfmlib_nhm_input_param_t
nhm_params
;
39
int
ret
;
40
unsigned
i
;
41
unsigned
long
sum
[
MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS
];
42
unsigned
count
;
43
unsigned
overhead_avg
[
MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS
];
44
45
private
:
46
PfmCodeAnalyser
(
const
char
*event0,
unsigned
int
cmask_v0,
bool
inv_v0,
47
const
char
*event1,
unsigned
int
cmask_v1,
bool
inv_v1,
48
const
char
*event2,
unsigned
int
cmask_v2,
bool
inv_v2,
49
const
char
*event3,
unsigned
int
cmask_v3,
bool
inv_v3);
// constructor hidden
50
PfmCodeAnalyser
(
PfmCodeAnalyser
const
&);
// copy constructor hidden
51
PfmCodeAnalyser
&
operator=
(
PfmCodeAnalyser
const
&);
// assign operator hidden
52
~PfmCodeAnalyser
();
// destructor hidden
53
54
public
:
55
static
PfmCodeAnalyser
&
Instance
(
const
char
*event0 =
"UNHALTED_CORE_CYCLES"
,
unsigned
int
cmask_v0 = 0,
bool
inv_v0 =
false
,
56
const
char
*event1 =
""
,
unsigned
int
cmask_v1 = 0,
bool
inv_v1 =
false
,
57
const
char
*event2 =
""
,
unsigned
int
cmask_v2 = 0,
bool
inv_v2 =
false
,
58
const
char
*event3 =
""
,
unsigned
int
cmask_v3 = 0,
bool
inv_v3 =
false
);
59
void
start
();
60
void
stop
();
61
void
stop_init
();
62
};
63
64
PfmCodeAnalyser::PfmCodeAnalyser
(
const
char
*event0,
unsigned
int
cmask_v0,
bool
inv_v0,
65
const
char
*event1,
unsigned
int
cmask_v1,
bool
inv_v1,
66
const
char
*event2,
unsigned
int
cmask_v2,
bool
inv_v2,
67
const
char
*event3,
unsigned
int
cmask_v3,
bool
inv_v3)
68
{
69
int
ax,bx,cx,dx;
70
cpuid
(1,ax,bx,cx,dx);
71
int
sse4_2_mask = 1 << 20;
72
nehalem
= cx & sse4_2_mask;
73
strcpy(
event_str
[0], event0);
74
strcpy(
event_str
[1], event1);
75
strcpy(
event_str
[2], event2);
76
strcpy(
event_str
[3], event3);
77
cmask
[0] = cmask_v0;
78
cmask
[1] = cmask_v1;
79
cmask
[2] = cmask_v2;
80
cmask
[3] = cmask_v3;
81
inv
[0] = inv_v0;
82
inv
[1] = inv_v1;
83
inv
[2] = inv_v2;
84
inv
[3] = inv_v3;
85
used_counters_number
= 0;
86
for
(
int
i
=0;
i
<
MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS
;
i
++)
87
{
88
if
(strlen(
event_str
[
i
])>0)
used_counters_number
++;
89
}
90
for
(
int
i
=0;
i
<
used_counters_number
;
i
++)
91
{
92
sum
[
i
] = 0;
93
overhead_avg
[
i
] = 0;
94
}
95
count
= 0;
96
if
(
pfm_initialize
() !=
PFMLIB_SUCCESS
)
97
{
98
printf(
"Cannot initialize perfmon!!\nExiting...\n"
);
99
exit
(0);
100
}
101
while
(
count
<3)
102
{
103
start
();
104
stop_init
();
105
}
106
for
(
int
i
=0;
i
<
used_counters_number
;
i
++)
107
{
108
sum
[
i
] = 0;
109
}
110
count
= 0;
111
while
(
count
<10)
112
{
113
start
();
114
stop_init
();
115
}
116
for
(
int
i
=0;
i
<
used_counters_number
;
i
++)
117
{
118
overhead_avg
[
i
] =
sum
[
i
]/
count
;
119
sum
[
i
] = 0;
120
}
121
count
= 0;
122
}
123
124
PfmCodeAnalyser
&
PfmCodeAnalyser::Instance
(
const
char
*event0,
unsigned
int
cmask_v0,
bool
inv_v0,
125
const
char
*event1,
unsigned
int
cmask_v1,
bool
inv_v1,
126
const
char
*event2,
unsigned
int
cmask_v2,
bool
inv_v2,
127
const
char
*event3,
unsigned
int
cmask_v3,
bool
inv_v3)
128
{
129
static
PfmCodeAnalyser
theSingleton(event0, cmask_v0, inv_v0, event1, cmask_v1, inv_v1, event2, cmask_v2, inv_v2, event3, cmask_v3, inv_v3);
130
return
theSingleton;
131
}
132
133
// start()
134
// initializes all the necessary structures to start the actual counting, calling pfm_start()
135
void
PfmCodeAnalyser::start
()
136
{
137
memset(&
ctx
,0,
sizeof
(
ctx
));
138
memset(&
inp
,0,
sizeof
(
inp
));
139
memset(&
outp
,0,
sizeof
(
outp
));
140
memset(
pd
, 0,
sizeof
(
pd
));
141
memset(
pc
, 0,
sizeof
(
pc
));
142
memset(&
load_arg
, 0,
sizeof
(
load_arg
));
143
memset(&
params
, 0,
sizeof
(
params
));
144
for
(
int
i
=0;
i
<
used_counters_number
;
i
++)
145
{
146
ret
=
pfm_find_full_event
(
event_str
[
i
], &
inp
.
pfp_events
[i]);
147
if
(
ret
!=
PFMLIB_SUCCESS
)
148
{
149
fprintf(stderr,
"ERROR: cannot find event: %s\naborting...\n"
,
event_str
[i]);
150
exit
(1);
151
}
152
}
153
inp
.
pfp_dfl_plm
=
PFM_PLM3
;
154
inp
.
pfp_event_count
=
used_counters_number
;
155
for
(
int
i
=0;
i
<
used_counters_number
;
i
++)
156
{
157
if
(
inv
[
i
])
158
{
159
(
params
.
pfp_core_counters
[
i
]).flags |=
PFM_CORE_SEL_INV
;
160
(
nhm_params
.
pfp_nhm_counters
[
i
]).flags |=
PFM_NHM_SEL_INV
;
161
}
162
if
(
cmask
[i]>0)
163
{
164
(
params
.
pfp_core_counters
[
i
]).cnt_mask =
cmask
[i];
165
(
nhm_params
.
pfp_nhm_counters
[
i
]).cnt_mask =
cmask
[i];
166
}
167
}
168
if
(
nehalem
)
169
{
170
ret
=
pfm_dispatch_events
(&
inp
, &
nhm_params
, &
outp
, NULL);
171
}
172
else
173
{
174
ret
=
pfm_dispatch_events
(&
inp
, &
params
, &
outp
, NULL);
175
}
176
if
(
ret
!=
PFMLIB_SUCCESS
)
177
{
178
fprintf(stderr,
"ERROR: cannot dispatch events: %s\naborting...\n"
,
pfm_strerror
(
ret
));
179
exit
(1);
180
}
181
for
(
unsigned
int
i
=0;
i
<
outp
.
pfp_pmc_count
;
i
++)
182
{
183
pc
[
i
].
reg_num
=
outp
.
pfp_pmcs
[
i
].
reg_num
;
184
pc
[
i
].
reg_value
=
outp
.
pfp_pmcs
[
i
].
reg_value
;
185
}
186
for
(
unsigned
int
i
=0;
i
<
outp
.
pfp_pmd_count
;
i
++)
187
{
188
pd
[
i
].
reg_num
=
outp
.
pfp_pmds
[
i
].
reg_num
;
189
pd
[
i
].
reg_value
= 0;
190
}
191
fd
=
pfm_create_context
(&
ctx
, NULL, 0, 0);
192
if
(
fd
== -1)
193
{
194
fprintf(stderr,
"ERROR: Context not created\naborting...\n"
);
195
exit
(1);
196
}
197
if
(
pfm_write_pmcs
(
fd
,
pc
,
outp
.
pfp_pmc_count
) == -1)
198
{
199
fprintf(stderr,
"ERROR: Could not write pmcs\naborting...\n"
);
200
exit
(1);
201
}
202
if
(
pfm_write_pmds
(
fd
,
pd
,
outp
.
pfp_pmd_count
) == -1)
203
{
204
fprintf(stderr,
"ERROR: Could not write pmds\naborting...\n"
);
205
exit
(1);
206
}
207
load_arg
.
load_pid
= getpid();
208
if
(
pfm_load_context
(
fd
, &
load_arg
) == -1)
209
{
210
fprintf(stderr,
"ERROR: Could not load context\naborting...\n"
);
211
exit
(1);
212
}
213
pfm_start
(
fd
, NULL);
214
}
215
216
217
218
// stop()
219
// const ModuleDescription& desc : description of the module that just finished its execution (we are only interested in its name)
220
// stops the counting calling pfm_stop() and stores the counting results into the "results" map
221
void
PfmCodeAnalyser::stop
()
222
{
223
pfm_stop
(
fd
);
224
if
(
pfm_read_pmds
(
fd
,
pd
,
inp
.
pfp_event_count
) == -1)
225
{
226
fprintf(stderr,
"ERROR: Could not read pmds\naborting...\n"
);
227
exit
(1);
228
}
229
230
for
(
int
i
=0;
i
<
used_counters_number
;
i
++)
231
{
232
sum
[
i
] += (
pd
[
i
].
reg_value
-
overhead_avg
[
i
]);
233
}
234
count
++;
235
close(
fd
);
236
}
237
238
void
PfmCodeAnalyser::stop_init
()
239
{
240
pfm_stop
(
fd
);
241
if
(
pfm_read_pmds
(
fd
,
pd
,
inp
.
pfp_event_count
) == -1)
242
{
243
fprintf(stderr,
"ERROR: Could not read pmds\naborting...\n"
);
244
exit
(1);
245
}
246
247
for
(
int
i
=0;
i
<
used_counters_number
;
i
++)
248
{
249
sum
[
i
] += (
pd
[
i
].
reg_value
);
250
}
251
count
++;
252
close(
fd
);
253
}
254
255
PfmCodeAnalyser::~PfmCodeAnalyser
()
256
{
257
for
(
int
i
=0;
i
<
used_counters_number
;
i
++)
258
{
259
printf(
"Event: %s\nTotal count:%lu\nNumber of counts:%u\nAverage count:%f\nOverhead removed:%u\n"
,
event_str
[
i
],
sum
[i],
count
, (
double
)
sum
[i]/
count
,
overhead_avg
[i]);
260
}
261
}
262
263
#endif //PfmCodeAnalyserH
Generated at Wed Mar 20 2013 17:59:39 for Gaudi Framework, version v23r7 by
Doxygen
version 1.8.2 written by
Dimitri van Heesch
, © 1997-2004