Performance-Monitoring Counters Library, for Intel/AMD Processors and Linux
This example introduces
hardware cycle and event counters, user interface
pmc_data_t -- raw data collected by pmc_read()
pmc_cycle_t
pmc_event_t
pmc_cycle_bits
pmc_event_bits
pmc_cycle() -- access functions for pmc_data_t
pmc_event()
pmc_second()
pmc_seconds_per_cycle
Previous example -- exclusive access
Download this example
Next example -- pmc_counter_t, intro
Return to Main Menu
Compile with
gcc -o menu5 -O `pmc_options` menu5.c -lpmc
Try these examples:
menu5
menu5 -p
menu5 -g 0
#include <pmc_lib.h>
int main(int argc, char * argv[])
{
pmc_control_t Ctl = pmc_control_null;
pmc_data_t t0, t1;
if (pmc_getargs(stderr, argv[0], &argc, &argv, &Ctl) == FALSE)
{ exit(1); }
printf("pmc_event_counters = %d\n", pmc_event_counters);
printf("sizeof(pmc_data_t) = %d\n", sizeof(pmc_data_t));
printf("sizeof(pmc_cycle_t) = %d\n", sizeof(pmc_cycle_t));
printf("sizeof(pmc_event_t) = %d\n", sizeof(pmc_event_t));
printf("pmc_cycle_bits = %d\n", pmc_cycle_bits);
printf("pmc_event_bits = %d\n", pmc_event_bits);
if (pmc_open(0) == FALSE) /* open /dev/pmc */
{ exit(1); }
pmc_read(&t0); /* read the counters */
/* do something */
pmc_read(&t1); /* read the counters */
pmc_close(); /* close /dev/pmc */
printf("t0.pmc_cycle() = %016llx\n", pmc_cycle(&t0));
printf("t0.pmc_event(0) = %016llx\n", pmc_event(&t0,0));
printf("t0.pmc_event(1) = %016llx\n", pmc_event(&t0,1));
printf("t1.pmc_cycle() = %016llx\n", pmc_cycle(&t1));
printf("t1.pmc_event(0) = %016llx\n", pmc_event(&t1,0));
printf("t1.pmc_event(1) = %016llx\n", pmc_event(&t1,1));
printf("t0.pmc_second() = %16.9f\n", pmc_second(pmc_cycle(&t0)));
printf("t1.pmc_second() = %16.9f\n", pmc_second(pmc_cycle(&t1)));
exit(0);
}
Synopsis
typedef struct { ... } pmc_data_t;
typedef unsigned long long int pmc_cycle_t;
typedef unsigned long long int pmc_event_t;
#define pmc_cycle_bits 64 /* Intel or AMD */
#define pmc_event_bits 40 /* 40 with Intel, 48 with AMD Athlon */
pmc_cycle_t pmc_cycle(const pmc_data_t * const a);
pmc_event_t pmc_event(const pmc_data_t * const a, const int i);
double pmc_second(const pmc_cycle_t c);
extern double pmc_seconds_per_cycle;
Naming convention
These values represent a moment in time, so cycle and event are singular.
The pmc_data_t type holds a consistent set of raw cycle and event counter
values obtained by pmc_read(). The components are opaque, and are translated
to pmc_cycle_t and pmc_event_t by pmc_cycle() and pmc_event(), respectively.
The effective numbers of bits in the counters are given by pmc_cycle_bits and
pmc_event_bits, and the types pmc_cycle_t and pmc_event_t will have at least
this many bits. There is no need to access the components of pmc_data_t
directly; depending on the processor, some of the bits may need to be filtered
out by pmc_event(). The typedef also contains an alignment request, which the
compiler respects as a global or static local, but not as an automatic local
on the runtime stack. In the current implementation, pmc_data_t is padded to
32 bytes, and aligned to a 32 byte boundary, so the data ideally exactly fills
one cache line; on the AMD Athlon, the padding is to 64 bytes.
Conversion from processor cycles to seconds via pmc_second() uses the MHz
rating supplied to pmc_getargs() by the -mhz option. If you did not use
pmc_getargs() to read from the command line, you should assign the appropriate
value to the global variable pmc_seconds_per_cycle, or you can accept the
value given by the installation.
Unless the cycle counter has been reset, it contains the number of processor
cycles since system startup. The event counters are often reset, and can
overflow in relatively short time periods if counting a frequent event. The
particular counter values are usually not relevant; use pmc_accumulate() to
compute the number of cycles and events associated with a time interval.
Forward References
pmc_read()
pmc_accumulate()
Performance-Monitoring Counters Library, for Intel/AMD Processors and Linux
Author: Don Heller, dheller@scl.ameslab.gov
Last revised: 2 August 2000