| The Gaudi Framework v30r0 (c919700c)

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

PfmCodeAnalyser.h
Go to the documentation of this file.
1 #ifndef PfmCodeAnalyserH
2 #define PfmCodeAnalyserH 1
3
4 #include <perfmon/perfmon.h>
5 #include <perfmon/perfmon_dfl_smpl.h>
6 #include <perfmon/pfmlib.h>
7 #include <perfmon/pfmlib_core.h>
8 #include <perfmon/pfmlib_intel_nhm.h>
9 #include <stdio.h>
10 #include <stdlib.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 ) \
21 __asm__ __volatile__( "cpuid" : "=a"( eax ), "=b"( ebx ), "=c"( ecx ), "=d"( edx ) : "a"( func ) );
22
23 class PfmCodeAnalyser
24 {
25 private:
26 int used_counters_number;
27 int nehalem;
28 pfmlib_input_param_t inp;
29 pfmlib_output_param_t outp;
30 pfarg_ctx_t ctx;
31 pfarg_pmd_t pd[NUM_PMDS];
32 pfarg_pmc_t pc[NUM_PMCS];
33 pfarg_load_t load_arg;
34 int fd;
35 char event_str[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS][MAX_EVT_NAME_LEN];
36 bool inv[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS];
37 unsigned int cmask[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS];
38 pfmlib_core_input_param_t params;
39 pfmlib_nhm_input_param_t nhm_params;
40 int ret;
41 unsigned i;
42 unsigned long sum[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS];
43 unsigned count;
44 unsigned overhead_avg[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS];
45
46 private:
47 PfmCodeAnalyser( const char* event0, unsigned int cmask_v0, bool inv_v0, const char* event1, unsigned int cmask_v1,
48 bool inv_v1, const char* event2, unsigned int cmask_v2, bool inv_v2, const char* event3,
49 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,
56 bool inv_v0 = false, const char* event1 = "", unsigned int cmask_v1 = 0,
57 bool inv_v1 = false, const char* event2 = "", unsigned int cmask_v2 = 0,
58 bool inv_v2 = false, const char* event3 = "", unsigned int cmask_v3 = 0,
59 bool inv_v3 = false );
60 void start();
61 void stop();
62 void stop_init();
63 };
64
65 PfmCodeAnalyser::PfmCodeAnalyser( const char* event0, unsigned int cmask_v0, bool inv_v0, const char* event1,
66 unsigned int cmask_v1, bool inv_v1, const char* event2, unsigned int cmask_v2,
67 bool inv_v2, 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 if ( strlen( event_str[i] ) > 0 ) used_counters_number++;
88 }
89 for ( int i = 0; i < used_counters_number; i++ ) {
90 sum[i] = 0;
91 overhead_avg[i] = 0;
92 }
93 count = 0;
94 if ( pfm_initialize() != PFMLIB_SUCCESS ) {
95 printf( "Cannot initialize perfmon!!\nExiting...\n" );
96 exit( 0 );
97 }
98 while ( count < 3 ) {
99 start();
100 stop_init();
101 }
102 for ( int i = 0; i < used_counters_number; i++ ) {
103 sum[i] = 0;
104 }
105 count = 0;
106 while ( count < 10 ) {
107 start();
108 stop_init();
109 }
110 for ( int i = 0; i < used_counters_number; i++ ) {
111 overhead_avg[i] = sum[i] / count;
112 sum[i] = 0;
113 }
114 count = 0;
115 }
116
117 PfmCodeAnalyser& PfmCodeAnalyser::Instance( const char* event0, unsigned int cmask_v0, bool inv_v0, const char* event1,
118 unsigned int cmask_v1, bool inv_v1, const char* event2,
119 unsigned int cmask_v2, bool inv_v2, const char* event3,
120 unsigned int cmask_v3, bool inv_v3 )
121 {
122 static PfmCodeAnalyser theSingleton( event0, cmask_v0, inv_v0, event1, cmask_v1, inv_v1, event2, cmask_v2, inv_v2,
123 event3, cmask_v3, inv_v3 );
124 return theSingleton;
125 }
126
127 // start()
128 // initializes all the necessary structures to start the actual counting, calling pfm_start()
129 void PfmCodeAnalyser::start()
130 {
131 memset( &ctx, 0, sizeof( ctx ) );
132 memset( &inp, 0, sizeof( inp ) );
133 memset( &outp, 0, sizeof( outp ) );
134 memset( pd, 0, sizeof( pd ) );
135 memset( pc, 0, sizeof( pc ) );
136 memset( &load_arg, 0, sizeof( load_arg ) );
137 memset( &params, 0, sizeof( params ) );
138 for ( int i = 0; i < used_counters_number; i++ ) {
139 ret = pfm_find_full_event( event_str[i], &inp.pfp_events[i] );
140 if ( ret != PFMLIB_SUCCESS ) {
141 fprintf( stderr, "ERROR: cannot find event: %s\naborting...\n", event_str[i] );
142 exit( 1 );
143 }
144 }
145 inp.pfp_dfl_plm = PFM_PLM3;
146 inp.pfp_event_count = used_counters_number;
147 for ( int i = 0; i < used_counters_number; i++ ) {
148 if ( inv[i] ) {
149 ( params.pfp_core_counters[i] ).flags |= PFM_CORE_SEL_INV;
150 ( nhm_params.pfp_nhm_counters[i] ).flags |= PFM_NHM_SEL_INV;
151 }
152 if ( cmask[i] > 0 ) {
153 ( params.pfp_core_counters[i] ).cnt_mask = cmask[i];
154 ( nhm_params.pfp_nhm_counters[i] ).cnt_mask = cmask[i];
155 }
156 }
157 if ( nehalem ) {
158 ret = pfm_dispatch_events( &inp, &nhm_params, &outp, NULL );
159 } else {
160 ret = pfm_dispatch_events( &inp, &params, &outp, NULL );
161 }
162 if ( ret != PFMLIB_SUCCESS ) {
163 fprintf( stderr, "ERROR: cannot dispatch events: %s\naborting...\n", pfm_strerror( ret ) );
164 exit( 1 );
165 }
166 for ( unsigned int i = 0; i < outp.pfp_pmc_count; i++ ) {
167 pc[i].reg_num = outp.pfp_pmcs[i].reg_num;
168 pc[i].reg_value = outp.pfp_pmcs[i].reg_value;
169 }
170 for ( unsigned int i = 0; i < outp.pfp_pmd_count; i++ ) {
171 pd[i].reg_num = outp.pfp_pmds[i].reg_num;
172 pd[i].reg_value = 0;
173 }
174 fd = pfm_create_context( &ctx, NULL, 0, 0 );
175 if ( fd == -1 ) {
176 fprintf( stderr, "ERROR: Context not created\naborting...\n" );
177 exit( 1 );
178 }
179 if ( pfm_write_pmcs( fd, pc, outp.pfp_pmc_count ) == -1 ) {
180 fprintf( stderr, "ERROR: Could not write pmcs\naborting...\n" );
181 exit( 1 );
182 }
183 if ( pfm_write_pmds( fd, pd, outp.pfp_pmd_count ) == -1 ) {
184 fprintf( stderr, "ERROR: Could not write pmds\naborting...\n" );
185 exit( 1 );
186 }
187 load_arg.load_pid = getpid();
188 if ( pfm_load_context( fd, &load_arg ) == -1 ) {
189 fprintf( stderr, "ERROR: Could not load context\naborting...\n" );
190 exit( 1 );
191 }
192 pfm_start( fd, NULL );
193 }
194
195 // stop()
196 // const ModuleDescription& desc : description of the module that just finished its execution (we are only interested in
197 // its name)
198 // stops the counting calling pfm_stop() and stores the counting results into the "results" map
199 void PfmCodeAnalyser::stop()
200 {
201 pfm_stop( fd );
202 if ( pfm_read_pmds( fd, pd, inp.pfp_event_count ) == -1 ) {
203 fprintf( stderr, "ERROR: Could not read pmds\naborting...\n" );
204 exit( 1 );
205 }
206
207 for ( int i = 0; i < used_counters_number; i++ ) {
208 sum[i] += ( pd[i].reg_value - overhead_avg[i] );
209 }
210 count++;
211 close( fd );
212 }
213
214 void PfmCodeAnalyser::stop_init()
215 {
216 pfm_stop( fd );
217 if ( pfm_read_pmds( fd, pd, inp.pfp_event_count ) == -1 ) {
218 fprintf( stderr, "ERROR: Could not read pmds\naborting...\n" );
219 exit( 1 );
220 }
221
222 for ( int i = 0; i < used_counters_number; i++ ) {
223 sum[i] += ( pd[i].reg_value );
224 }
225 count++;
226 close( fd );
227 }
228
229 PfmCodeAnalyser::~PfmCodeAnalyser()
230 {
231 for ( int i = 0; i < used_counters_number; i++ ) {
232 printf( "Event: %s\nTotal count:%lu\nNumber of counts:%u\nAverage count:%f\nOverhead removed:%u\n", event_str[i],
233 sum[i], count, (double)sum[i] / count, overhead_avg[i] );
234 }
235 }
236
237 #endif // PfmCodeAnalyserH
pfmlib_output_param_t::pfp_pmds
pfmlib_reg_t pfp_pmds[PFMLIB_MAX_PMDS]
Definition: pfmlib.h:129
PfmCodeAnalyser::load_arg
pfarg_load_t load_arg
Definition: PfmCodeAnalyser.h:33
MAX_EVT_NAME_LEN
#define MAX_EVT_NAME_LEN
Definition: PfmCodeAnalyser.h:15
pfm_write_pmds
os_err_t pfm_write_pmds(int fd, pfarg_pmd_t *pmds, int count)
PFM_NHM_SEL_INV
#define PFM_NHM_SEL_INV
Definition: pfmlib_intel_nhm.h:103
pfm_create_context
os_err_t pfm_create_context(pfarg_ctx_t *ctx, char *smpl_name, void *smpl_arg, size_t smpl_size)
PFM_PLM3
#define PFM_PLM3
Definition: pfmlib.h:53
NUM_PMDS
#define NUM_PMDS
Definition: PfmCodeAnalyser.h:17
pfm_strerror
char * pfm_strerror(int code)
PfmCodeAnalyser::nhm_params
pfmlib_nhm_input_param_t nhm_params
Definition: PfmCodeAnalyser.h:39
PfmCodeAnalyser::fd
int fd
Definition: PfmCodeAnalyser.h:34
pfmlib_input_param_t::pfp_events
pfmlib_event_t pfp_events[PFMLIB_MAX_PMCS]
Definition: pfmlib.h:112
PFM_CORE_SEL_INV
#define PFM_CORE_SEL_INV
Definition: pfmlib_core.h:68
MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS
#define MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS
Definition: PfmCodeAnalyser.h:19
pfmlib_nhm_input_param_t::pfp_nhm_counters
pfmlib_nhm_counter_t pfp_nhm_counters[PMU_NHM_NUM_COUNTERS]
Definition: pfmlib_intel_nhm.h:139
PfmCodeAnalyser::ctx
pfarg_ctx_t ctx
Definition: PfmCodeAnalyser.h:30
PFMLIB_SUCCESS
#define PFMLIB_SUCCESS
Definition: pfmlib.h:267
PfmCodeAnalyser::event_str
char event_str[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS][MAX_EVT_NAME_LEN]
Definition: PfmCodeAnalyser.h:35
pfmlib_input_param_t::pfp_dfl_plm
unsigned int pfp_dfl_plm
Definition: pfmlib.h:109
NUM_PMCS
#define NUM_PMCS
Definition: PfmCodeAnalyser.h:16
pfmlib_input_param_t
Definition: pfmlib.h:107
pfarg_pmd_t::reg_num
uint16_t reg_num
Definition: perfmon_v2.h:39
PfmCodeAnalyser::ret
int ret
Definition: PfmCodeAnalyser.h:40
PfmCodeAnalyser::count
unsigned count
Definition: PfmCodeAnalyser.h:43
pfm_write_pmcs
os_err_t pfm_write_pmcs(int fd, pfarg_pmc_t *pmcs, int count)
pfm_dispatch_events
pfm_err_t pfm_dispatch_events(pfmlib_input_param_t *p, void *model_in, pfmlib_output_param_t *q, void *model_out)
pfmlib_output_param_t::pfp_pmc_count
unsigned int pfp_pmc_count
Definition: pfmlib.h:126
pfmlib_reg_t::reg_value
unsigned long long reg_value
Definition: pfmlib.h:97
pfmlib_output_param_t::pfp_pmd_count
unsigned int pfp_pmd_count
Definition: pfmlib.h:127
pfm_find_full_event
pfm_err_t pfm_find_full_event(const char *str, pfmlib_event_t *e)
pfarg_load_t
Definition: perfmon_v2.h:68
PfmCodeAnalyser::params
pfmlib_core_input_param_t params
Definition: PfmCodeAnalyser.h:38
PfmCodeAnalyser::cmask
unsigned int cmask[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS]
Definition: PfmCodeAnalyser.h:37
PfmCodeAnalyser
Definition: PfmCodeAnalyser.h:23
pfmlib_core.h
PfmCodeAnalyser::operator=
PfmCodeAnalyser & operator=(PfmCodeAnalyser const &)
pfmlib_intel_nhm.h
PfmCodeAnalyser::pc
pfarg_pmc_t pc[NUM_PMCS]
Definition: PfmCodeAnalyser.h:32
pfmlib_core_input_param_t
Definition: pfmlib_core.h:78
pfmlib_reg_t::reg_num
unsigned int reg_num
Definition: pfmlib.h:99
PfmCodeAnalyser::pd
pfarg_pmd_t pd[NUM_PMDS]
Definition: PfmCodeAnalyser.h:31
pfarg_pmc_t::reg_num
uint16_t reg_num
Definition: perfmon_v2.h:28
PfmCodeAnalyser::overhead_avg
unsigned overhead_avg[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS]
Definition: PfmCodeAnalyser.h:44
perfmon_dfl_smpl.h
pfarg_pmd_t
Definition: perfmon_v2.h:38
PfmCodeAnalyser::sum
unsigned long sum[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS]
Definition: PfmCodeAnalyser.h:42
pfmlib_output_param_t
Definition: pfmlib.h:125
pfarg_ctx_t
Definition: perfmon_v2.h:18
pfm_start
os_err_t pfm_start(int fd, pfarg_start_t *start)
pfm_initialize
pfm_err_t pfm_initialize(void)
pfmlib_nhm_input_param_t
Definition: pfmlib_intel_nhm.h:138
pfarg_load_t::load_pid
uint32_t load_pid
Definition: perfmon_v2.h:69
pfmlib.h
cpuid
#define cpuid(func, eax, ebx, ecx, edx)
Definition: PfmCodeAnalyser.h:20
PfmCodeAnalyser::used_counters_number
int used_counters_number
Definition: PfmCodeAnalyser.h:26
PfmCodeAnalyser::nehalem
int nehalem
Definition: PfmCodeAnalyser.h:27
PfmCodeAnalyser::~PfmCodeAnalyser
~PfmCodeAnalyser()
Definition: PfmCodeAnalyser.h:229
PfmCodeAnalyser::inp
pfmlib_input_param_t inp
Definition: PfmCodeAnalyser.h:28
pfarg_pmc_t
Definition: perfmon_v2.h:27
PfmCodeAnalyser::stop_init
void stop_init()
Definition: PfmCodeAnalyser.h:214
pfm_load_context
os_err_t pfm_load_context(int fd, pfarg_load_t *load)
PfmCodeAnalyser::PfmCodeAnalyser
PfmCodeAnalyser(const char *event0, unsigned int cmask_v0, bool inv_v0, const char *event1, unsigned int cmask_v1, bool inv_v1, const char *event2, unsigned int cmask_v2, bool inv_v2, const char *event3, unsigned int cmask_v3, bool inv_v3)
Definition: PfmCodeAnalyser.h:65
pfm_read_pmds
os_err_t pfm_read_pmds(int fd, pfarg_pmd_t *pmds, int count)
pfarg_pmc_t::reg_value
uint64_t reg_value
Definition: perfmon_v2.h:31
PfmCodeAnalyser::inv
bool inv[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS]
Definition: PfmCodeAnalyser.h:36
pfmlib_output_param_t::pfp_pmcs
pfmlib_reg_t pfp_pmcs[PFMLIB_MAX_PMCS]
Definition: pfmlib.h:128
pfmlib_core_input_param_t::pfp_core_counters
pfmlib_core_counter_t pfp_core_counters[PMU_CORE_NUM_COUNTERS]
Definition: pfmlib_core.h:79
perfmon.h
PfmCodeAnalyser::outp
pfmlib_output_param_t outp
Definition: PfmCodeAnalyser.h:29
pfm_stop
os_err_t pfm_stop(int fd)
PfmCodeAnalyser::Instance
static PfmCodeAnalyser & Instance(const char *event0="UNHALTED_CORE_CYCLES", unsigned int cmask_v0=0, bool inv_v0=false, const char *event1="", unsigned int cmask_v1=0, bool inv_v1=false, const char *event2="", unsigned int cmask_v2=0, bool inv_v2=false, const char *event3="", unsigned int cmask_v3=0, bool inv_v3=false)
Definition: PfmCodeAnalyser.h:117
pfarg_pmd_t::reg_value
uint64_t reg_value
Definition: perfmon_v2.h:42
PfmCodeAnalyser::start
void start()
Definition: PfmCodeAnalyser.h:129
pfmlib_input_param_t::pfp_event_count
unsigned int pfp_event_count
Definition: pfmlib.h:108
PfmCodeAnalyser::i
unsigned i
Definition: PfmCodeAnalyser.h:41
PfmCodeAnalyser::stop
void stop()
Definition: PfmCodeAnalyser.h:199