| # Gaudi Framework, version v23r1 |

Home |  | Generated: Wed Feb 29 2012

# PfmCodeAnalyser.h

Go to the documentation of this file.

    00001 #ifndef PfmCodeAnalyserH
    00002 #define PfmCodeAnalyserH 1
    00003
    00004 #include <stdlib.h>
    00005 #include <stdio.h>
    00006 #include <perfmon/pfmlib.h>
    00007 #include <perfmon/perfmon.h>
    00008 #include <perfmon/perfmon_dfl_smpl.h>
    00009 #include <perfmon/pfmlib_core.h>
    00010 #include <perfmon/pfmlib_intel_nhm.h>
    00011 #include <string.h>
    00012 #include <sys/types.h>
    00013 #include <unistd.h>
    00014
    00015 #define MAX_EVT_NAME_LEN 256
    00016 #define NUM_PMCS PFMLIB_MAX_PMCS
    00017 #define NUM_PMDS PFMLIB_MAX_PMDS
    00018 #define FMT_NAME PFM_DFL_SMPL_NAME
    00019 #define MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS 4
    00020 #define cpuid(func,eax,ebx,ecx,edx)     __asm__ __volatile__ ("cpuid": "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (func));
    00021
    00022 class PfmCodeAnalyser
    00023 {
    00024  private:
    00025   int used_counters_number;
    00026   int nehalem;
    00027   pfmlib_input_param_t inp;
    00028   pfmlib_output_param_t outp;
    00029   pfarg_ctx_t ctx;
    00030   pfarg_pmd_t pd[NUM_PMDS];
    00031   pfarg_pmc_t pc[NUM_PMCS];
    00032   pfarg_load_t load_arg;
    00033   int fd;
    00034   char event_str[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS][MAX_EVT_NAME_LEN];
    00035   bool inv[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS];
    00036   unsigned int cmask[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS];
    00037   pfmlib_core_input_param_t params;
    00038   pfmlib_nhm_input_param_t nhm_params;
    00039   int ret;
    00040   unsigned i;
    00041   unsigned long sum[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS];
    00042   unsigned count;
    00043   unsigned overhead_avg[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS];
    00044
    00045  private:
    00046   PfmCodeAnalyser(const char *event0, unsigned int cmask_v0, bool inv_v0,
    00047                   const char *event1, unsigned int cmask_v1, bool inv_v1,
    00048                   const char *event2, unsigned int cmask_v2, bool inv_v2,
    00049                   const char *event3, unsigned int cmask_v3, bool inv_v3); // constructor hidden
    00050   PfmCodeAnalyser(PfmCodeAnalyser const&); // copy constructor hidden
    00051   PfmCodeAnalyser& operator=(PfmCodeAnalyser const&); // assign operator hidden
    00052   ~PfmCodeAnalyser(); // destructor hidden
    00053
    00054  public:
    00055   static PfmCodeAnalyser& Instance(const char *event0 = "UNHALTED_CORE_CYCLES", unsigned int cmask_v0 = 0, bool inv_v0 = false,
    00056                                    const char *event1 = "", unsigned int cmask_v1 = 0, bool inv_v1 = false,
    00057                                    const char *event2 = "", unsigned int cmask_v2 = 0, bool inv_v2 = false,
    00058                                    const char *event3 = "", unsigned int cmask_v3 = 0, bool inv_v3 = false);
    00059   void start();
    00060   void stop();
    00061   void stop_init();
    00062 };
    00063
    00064 PfmCodeAnalyser::PfmCodeAnalyser(const char *event0, unsigned int cmask_v0, bool inv_v0,
    00065                                  const char *event1, unsigned int cmask_v1, bool inv_v1,
    00066                                  const char *event2, unsigned int cmask_v2, bool inv_v2,
    00067                                  const char *event3, unsigned int cmask_v3, bool inv_v3)
    00068 {
    00069  int ax,bx,cx,dx;
    00070  cpuid(1,ax,bx,cx,dx);
    00071  int sse4_2_mask = 1 << 20;
    00072  nehalem = cx & sse4_2_mask;
    00073  strcpy(event_str[0], event0);
    00074  strcpy(event_str[1], event1);
    00075  strcpy(event_str[2], event2);
    00076  strcpy(event_str[3], event3);
    00077  cmask[0] = cmask_v0;
    00078  cmask[1] = cmask_v1;
    00079  cmask[2] = cmask_v2;
    00080  cmask[3] = cmask_v3;
    00081  inv[0] = inv_v0;
    00082  inv[1] = inv_v1;
    00083  inv[2] = inv_v2;
    00084  inv[3] = inv_v3;
    00085  used_counters_number = 0;
    00086  for(int i=0; i<MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS; i++)
    00087  {
    00088   if(strlen(event_str[i])>0) used_counters_number++;
    00089  }
    00090  for(int i=0; i<used_counters_number; i++)
    00091  {
    00092   sum[i] = 0;
    00093   overhead_avg[i] = 0;
    00094  }
    00095  count = 0;
    00096  if(pfm_initialize() != PFMLIB_SUCCESS)
    00097  {
    00098   printf("Cannot initialize perfmon!!\nExiting...\n");
    00099   exit(0);
    00100  }
    00101  while(count<3)
    00102  {
    00103   start();
    00104   stop_init();
    00105  }
    00106  for(int i=0; i<used_counters_number; i++)
    00107  {
    00108   sum[i] = 0;
    00109  }
    00110  count = 0;
    00111  while(count<10)
    00112  {
    00113   start();
    00114   stop_init();
    00115  }
    00116  for(int i=0; i<used_counters_number; i++)
    00117  {
    00118   overhead_avg[i] = sum[i]/count;
    00119   sum[i] = 0;
    00120  }
    00121  count = 0;
    00122 }
    00123
    00124 PfmCodeAnalyser& PfmCodeAnalyser::Instance(const char *event0, unsigned int cmask_v0, bool inv_v0,
    00125                                            const char *event1, unsigned int cmask_v1, bool inv_v1,
    00126                                            const char *event2, unsigned int cmask_v2, bool inv_v2,
    00127                                            const char *event3, unsigned int cmask_v3, bool inv_v3)
    00128 {
    00129  static PfmCodeAnalyser theSingleton(event0, cmask_v0, inv_v0, event1, cmask_v1, inv_v1, event2, cmask_v2, inv_v2, event3, cmask_v3, inv_v3);
    00130  return theSingleton;
    00131 }
    00132
    00133  // start()
    00134  // initializes all the necessary structures to start the actual counting, calling pfm_start()
    00135 void PfmCodeAnalyser::start()
    00136 {
    00137  memset(&ctx,0, sizeof(ctx));
    00138  memset(&inp,0, sizeof(inp));
    00139  memset(&outp,0, sizeof(outp));
    00140  memset(pd, 0, sizeof(pd));
    00141  memset(pc, 0, sizeof(pc));
    00142  memset(&load_arg, 0, sizeof(load_arg));
    00143  memset(&params, 0, sizeof(params));
    00144  for(int i=0; i<used_counters_number; i++)
    00145  {
    00146   ret = pfm_find_full_event(event_str[i], &inp.pfp_events[i]);
    00147   if(ret != PFMLIB_SUCCESS)
    00148   {
    00149    fprintf(stderr, "ERROR: cannot find event: %s\naborting...\n", event_str[i]);
    00150    exit(1);
    00151   }
    00152  }
    00153  inp.pfp_dfl_plm = PFM_PLM3;
    00154  inp.pfp_event_count = used_counters_number;
    00155  for(int i=0; i<used_counters_number; i++)
    00156  {
    00157   if(inv[i])
    00158   {
    00159    (params.pfp_core_counters[i]).flags |= PFM_CORE_SEL_INV;
    00160    (nhm_params.pfp_nhm_counters[i]).flags |= PFM_NHM_SEL_INV;
    00161   }
    00162   if(cmask[i]>0)
    00163   {
    00164    (params.pfp_core_counters[i]).cnt_mask = cmask[i];
    00165    (nhm_params.pfp_nhm_counters[i]).cnt_mask = cmask[i];
    00166   }
    00167  }
    00168  if(nehalem)
    00169  {
    00170   ret = pfm_dispatch_events(&inp, &nhm_params, &outp, NULL);
    00171  }
    00172  else
    00173  {
    00174   ret = pfm_dispatch_events(&inp, &params, &outp, NULL);
    00175  }
    00176  if(ret != PFMLIB_SUCCESS)
    00177  {
    00178   fprintf(stderr, "ERROR: cannot dispatch events: %s\naborting...\n", pfm_strerror(ret));
    00179   exit(1);
    00180  }
    00181  for(unsigned int i=0; i<outp.pfp_pmc_count; i++)
    00182  {
    00183   pc[i].reg_num = outp.pfp_pmcs[i].reg_num;
    00184   pc[i].reg_value = outp.pfp_pmcs[i].reg_value;
    00185  }
    00186  for(unsigned int i=0; i<outp.pfp_pmd_count; i++)
    00187  {
    00188   pd[i].reg_num = outp.pfp_pmds[i].reg_num;
    00189   pd[i].reg_value = 0;
    00190  }
    00191  fd = pfm_create_context(&ctx, NULL, 0, 0);
    00192  if(fd == -1)
    00193  {
    00194   fprintf(stderr, "ERROR: Context not created\naborting...\n");
    00195   exit(1);
    00196  }
    00197  if(pfm_write_pmcs(fd, pc, outp.pfp_pmc_count) == -1)
    00198  {
    00199   fprintf(stderr, "ERROR: Could not write pmcs\naborting...\n");
    00200   exit(1);
    00201  }
    00202  if(pfm_write_pmds(fd, pd, outp.pfp_pmd_count) == -1)
    00203  {
    00204   fprintf(stderr, "ERROR: Could not write pmds\naborting...\n");
    00205   exit(1);
    00206  }
    00207  load_arg.load_pid = getpid();
    00208  if(pfm_load_context(fd, &load_arg) == -1)
    00209  {
    00210   fprintf(stderr, "ERROR: Could not load context\naborting...\n");
    00211   exit(1);
    00212  }
    00213  pfm_start(fd, NULL);
    00214 }
    00215
    00216
    00217
    00218  // stop()
    00219  // const ModuleDescription& desc : description of the module that just finished its execution (we are only interested in its name)
    00220  // stops the counting calling pfm_stop() and stores the counting results into the "results" map
    00221 void PfmCodeAnalyser::stop()
    00222 {
    00223  pfm_stop(fd);
    00224  if(pfm_read_pmds(fd, pd, inp.pfp_event_count) == -1)
    00225  {
    00226   fprintf(stderr, "ERROR: Could not read pmds\naborting...\n");
    00227   exit(1);
    00228  }
    00229
    00230  for(int i=0; i<used_counters_number; i++)
    00231  {
    00232   sum[i] += (pd[i].reg_value - overhead_avg[i]);
    00233  }
    00234  count++;
    00235  close(fd);
    00236 }
    00237
    00238 void PfmCodeAnalyser::stop_init()
    00239 {
    00240  pfm_stop(fd);
    00241  if(pfm_read_pmds(fd, pd, inp.pfp_event_count) == -1)
    00242  {
    00243   fprintf(stderr, "ERROR: Could not read pmds\naborting...\n");
    00244   exit(1);
    00245  }
    00246
    00247  for(int i=0; i<used_counters_number; i++)
    00248  {
    00249   sum[i] += (pd[i].reg_value);
    00250  }
    00251  count++;
    00252  close(fd);
    00253 }
    00254
    00255 PfmCodeAnalyser::~PfmCodeAnalyser()
    00256 {
    00257  for(int i=0; i<used_counters_number; i++)
    00258  {
    00259   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]);
    00260  }
    00261 }
    00262
    00263 #endif //PfmCodeAnalyserH

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines