Gaudi Framework, version v23r9

Home   Generated: Thu Jul 18 2013
 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>
9 #include <perfmon/pfmlib_core.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 
23 {
24  private:
26  int nehalem;
33  int fd;
39  int ret;
40  unsigned i;
42  unsigned count;
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;
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;
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()
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  {
147  if(ret != PFMLIB_SUCCESS)
148  {
149  fprintf(stderr, "ERROR: cannot find event: %s\naborting...\n", event_str[i]);
150  exit(1);
151  }
152  }
155  for(int i=0; i<used_counters_number; i++)
156  {
157  if(inv[i])
158  {
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  {
185  }
186  for(unsigned int i=0; i<outp.pfp_pmd_count; i++)
187  {
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
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 
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 
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 Thu Jul 18 2013 12:18:04 for Gaudi Framework, version v23r9 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004