Jump to content United States-English
HP.com Home Products and Services Support and Drivers Solutions How to Buy
» Contact HP

hp.com home


libpfm-2.0 library code examples

» 

HP Labs

» Research
» News and events
» Technical reports
» About HP Labs
» Careers @ HP Labs
» People
» Worldwide sites
» Downloads
Content starts here

Here we present some simple examples of how to use the libpfm library. There is also more complete set of examples included with the library source code. The example on this page use version 2.0 of the library which is not compatible with version 3.0. For version 3.0 examples, click here.

For simple examples on how to count events, you can look at the examples in the perfmon section.

Here we present an example using an Itanium 2 specific feature, namely the opcode matcher PMC8. Statements higlighted in green show Itanium 2 specific code.

The following extra examples can also be downloaded:

  • a example of how to use the Data EAR cache mode on Itanium can be found here.
  • a example of how to use the Data EAR cache mode on Itanium 2 can be found here.

Example of a self-monitoring process using the opcode matcher PMC8 on Itanium 2

/*
 * main libpfm include file
 */
#include <sys/types.h>
#include <stdio.h>
#include <errno.h>
#include <perfmon/pfmlib.h>
#include <perfmon/pfmlib_itanium2.h>

int
main(int argc, char **argv)
{
  char *name;
  int i, ret;
  pid_t mypid = getpid();
  pfmlib_param_t evt;
  pfmlib_ita2_param_t ita2_evt;
  pfarg_reg_t pd[1];
  pfarg_context_t ctx[1];

  /*
   * Initialize libpfm (required before we use it)
   */
  if (pfm_initialize() != PFMLIB_SUCCESS) {
    fprintf(stderr, "cannot initialize libpfm\n");
    exit(1);
  }
  
  /*
   * initialize local variables
   */
  memset(pd, 0, sizeof(pd));
  memset(ctx, 0, sizeof(ctx));
  memset(&evt,0, sizeof(evt));
  memset(&ita2_evt,0, sizeof(ita2_evt));

  /*
   * find event descriptor for our event
   */
  ret = pfm_find_event("IA64_TAGGED_INST_RETIRED_IBRP0_PMC8",
                       &evt.pfp_events[0].event);
  if (ret != PFMLIB_SUCCESS) {
     fprintf(stderr,"ia64_tagged_inst_retired not found\n");
     exit(1);
   }
  /*
   * setup the magic number in the Itanium 2 specific
   * structure (required, otherwise config will be ignored).
   */
   ita2_evt.pfp_magic = PFMLIB_ITA2_PARAM_MAGIC;

  /*
   * link the model specific description to the
   * generic description
   */
  evt.pfp_model = &ita2_evt;

  /*
   * indicate that we are using the PMC8 opcode matcher
   */
  ita2_evt.pfp_ita2_pmc8.opcm_used = 1;

  /*
   * load value to install in PMC8 (some control fields may be 
   * modified by library). Here it is the pattern for the
   * br.cloop instruction.
   */
  ita2_evt.pfp_ita2_pmc8.pmc_val = 0x1400028003fff1fa;



  /*
   * set the default privilege mode for all counters:
   *   PFM_PLM3 : user level only
   */
  evt.pfp_dfl_plm = PFM_PLM3; 

  /*
   * how many events we are interested in
   */
  evt.pfp_event_count = 1;

  /*
   * let the library figure out the values for the PMCS
   */
  ret = pfm_dispatch_events(&evt);
  if (ret != PFMLIB_SUCCESS) {
    fprintf(stderr, "cannot configure events: %s\n", 
            pfm_strerror(ret));
    exit(1);
  }
  /*
   * now create the context for self monitoring/per-task
   */
   ret = perfmonctl(mypid, PFM_CREATE_CONTEXT, ctx, 1);
  if (ret == -1) {
    fprintf(stderr, "PFM_CREATE_CONTEXT errno %d\n", errno);
    exit(1);
  }
  /*
   * Initialize the PMU with safe values. psr.up is cleared.
   */
   ret = perfmonctl(mypid, PFM_ENABLE, NULL, 0);
  if (ret  == -1) {
    fprintf(stderr, "PFM_ENABLE errno %d\n",errno);
    exit(1);
  }

  /*
   * Now prepare the arguments to write the PMDs.
   * counters are pair of PMC/PMD and they use the same
   * index. We propagate the indexes used for the PMCs
   * back to their equivalent PMDs.
   */
  for (i=0; i < evt.pfp_event_count; i++) {
    pd[i].reg_num = evt.pfp_pc[i].reg_num;
  }
  /*
   * Now program the PMC registers.
   * In this case, we write two PMC registers
   */
   ret = perfmonctl(mypid, PFM_WRITE_PMCS, evt.pfp_pc, evt.pfp_pc_count);
  if (ret == -1) {
    fprintf(stderr, "PFM_WRITE_PMCS errno %d\n",errno);
    exit(1);
  }
  /*
   * We reset the PMDs that go with the PMCs
   */
   ret = perfmonctl(mypid, PFM_WRITE_PMDS, pd, evt.pfp_event_count);
  if (ret == -1) {
    fprintf(stderr, "PFM_WRITE_PMDS errno %d\n",errno);
    exit(1);
  }

  /*
   * start monitoring. For self-monitoring tasks, it is possible to
   * use the lightweight library call instead of PFM_START
   */
  pfm_start();

  /* 
   *
   * code to monitor goes here 
   *
   */

  /*
   * stop monitoring. For self-monitoring tasks, it is possible to
   * use the lightweight library call instead of PFM_STOP
   */
  pfm_stop();

  /*
   * now read the results
   */
   ret = perfmonctl(mypid, PFM_READ_PMDS, pd, evt.pfp_event_count);
  if (ret == -1) {
    fprintf(stderr, "PFM_READ_PMDS errno %d\n",errno);
    exit(1);
  }
  /*
   * and finally, print the results
   */
  for (i=0; i < evt.pfp_event_count; i++) {
    pfm_get_event_name(evt.pfp_events[i].event, &name);
    printf("PMD%u %20lu %s\n", 
            pd[i].reg_num, 
            pd[i].reg_value, 
            name);
  }
  /*
   * destroy the perfmon context
   */
   ret = perfmonctl(mypid, PFM_DESTROY_CONTEXT, NULL, 0);
  if (ret == -1) {
    fprintf(stderr, "PFM_DESTROY errno %d\n",errno);
    exit(1);
  }
  return 0;
}


perfmon project links

» project home
» perfmon overview
» libpfm overview
» pfmon overview
» mailing list
» downloads
» bibliography
» presentations

libpfm links

» FAQ
» examples
» man pages
Printable version
Privacy statement Using this site means you accept its terms Feedback to HP Labs
© 2009 Hewlett-Packard Development Company, L.P.