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