Performance-Monitoring Counters Library, for Intel/AMD Processors and Linux
This example introduces
   Making a time-line 
   pmc_print_results() 

Previous example       -- data acquisition
Download this example
Next example           -- interrupts and signal handlers
Return to Main Menu


Compile with gcc -o menu9 -O `pmc_options` menu9.c -lpmc Try these examples: menu9 -g 0 menu9 --e 0,1 (Pentium) menu9 --e 67,69 (Pentium Pro) menu9 --e 22 --u 1,0 --o 0,1 (Pentium) menu9 --e 121 --u 1,0 --o 0,1 (Pentium Pro) rabbit -o zap --e 0x16,0x28 foo (Pentium) rabbit -o zap --e 0x16,0x17 foo (Pentium) rabbit -o zap --e 192,67 foo (Pentium Pro) rabbit -o zap --e 192,194 foo (Pentium Pro) gnuplot zap/plot ls -l zap more zap/summary zap/input zap/data.0 zap/rawdata.0 zap/plot
#include <pmc_lib.h> /* events per second */ /* instantaneous rate over one time interval * CAUTION -- use this only after calling pmc_accumulate() */ double pmc_rate(double rate[pmc_event_counters], const pmc_data_t * const a) { double sec = pmc_second(pmc_cycle(a)); int i; for (i = 0; i < pmc_event_counters; i++) { rate[i] = (double) pmc_event(a,i) / sec; } return sec; } /* average rate over accumulated time intervals */ double pmc_rates(double rates[pmc_event_counters], const pmc_counter_t * const a) { double sec = pmc_seconds(pmc_sum_cycles(a)); int i; for (i = 0; i < pmc_event_counters; i++) { rates[i] = (double) pmc_sum_events(a,i) / sec; } return sec; } int main(int argc, char * argv[]) { pmc_control_t Ctl = pmc_control_null; pmc_data_t t0, t1; pmc_cycles_t elapsed; double Sec, Rate[pmc_event_counters]; int i, j; /* read command line, initialize internal data structures */ if (pmc_getargs(stderr, argv[0], &argc, &argv, &Ctl) == FALSE) { exit(1); } if (pmc_open(0) == FALSE) /* open /dev/pmc */ { exit(1); } pmc_start(); /* starting point for elapsed time */ for (i = 0; i < 5; i++) { /* set the counter control registers */ pmc_select(&Ctl.counters[0]); pmc_read(&t0); /* read the counters */ /* do something */ pmc_read(&t1); /* read the counters */ /* counters[0] += (t1 -= t0) */ elapsed = pmc_accumulate(&Ctl.counters[0], &t1, &t0); printf("elapsed time: %15.9f sec.\n", pmc_seconds(elapsed)); Sec = pmc_rate(Rate, &t1); printf("instantaneous: %15.9f sec.", Sec); for (j = 0; j < pmc_event_counters; j++) { printf(" %12.2f", Rate[j]); } printf(" events/sec.\n"); Sec = pmc_rates(Rate, &Ctl.counters[0]); printf("cumulative: %15.9f sec.", Sec); for (j = 0; j < pmc_event_counters; j++) { printf(" %12.2f", Rate[j]); } printf(" events/sec.\n\n"); } pmc_close(); /* close /dev/pmc */ pmc_print_results(argc, argv, &Ctl); exit(0); }
Synopsis int pmc_print_results (const int argc, char * argv[], const pmc_control_t * ctl);
There are two ways to view the performance measurements: by a statistical summary as given by pmc_print_results(), or by graphing the individual results as they are obtained. rabbit, with the -output option, will do both, even producing a gnuplot script to draw the graphs. gnuplot was chosen because it is freely available; other plotting packages might be preferred for interactive work on large output files. This example uses events per second, but in some cases it would be more reasonable to use events per cycle, as shown in the previous examples. The return value of pmc_print_results() is the exit status of the child process from pmc_run_command(), or 0 if pmc_run_command() was not used.

Performance-Monitoring Counters Library, for Intel/AMD Processors and Linux
Author: Don Heller, dheller@scl.ameslab.gov
Last revised: 2 August 2000