| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- 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
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