Most of today's processors are equipped with hardware performance counters. Such counters can be used to count micro-architecture events in order to analyse the target program to improve its performance. Generally, profiling and analysing are the main goals of these counters.
Based on research papers presented in literatures, these counters lack accuracy. For example, if we want to count the number of retired instructions in a given code, the value may be change from run to another, perturbation problem. Several guidelines have been discussed to increase accuracy in measurements. Monitoring multiple events can provide better understand about the program being executed, and therefore increasing measurements accuracy.
Authors of User-defined events for hardware performance monitoring have been proposed a new method to enable users to define their own events to be used by PAPI (Performance API) which is an infrastructure widely used to access the hardware performacne counters in easy way. Unfortunately, the paper does not explain in detail how we define user-defined events and use them in our program.
For example (based on PAPI), I seek to define a new event that involves n native/preset events like (PAPI_TOT_INS, PAPI_BR_TKN and PAPI_STR_INS), and then use it as a single event in my code.
edited:
Based on the mentioned paper, I set the environment variable PAPI USER_EVENTS FILE to indicate to the file that contains user-defined events and this file will initiate and parse by calling PAPI_library_init function. The event_file is very simple (just for testing):
#define a 5
tot_ins, PAPI_TOT_CYC|a|*
My code looks like this:
#include <stdio.h>
#include <stdlib.h>
#include <papi.h>
int main(int argc, char** argv) {
long_long val[10000];
int EventSet = PAPI_NULL;
long_long values[1];
PAPI_library_init(PAPI_VER_CURRENT);
PAPI_create_eventset(&EventSet);
//tot_ins is the name of the event defined in event-file
int counter_code;
PAPI_event_name_to_code("tot_ins",& counter_code);
printf("code =%x\n",counter_code);
PAPI_add_event(EventSet,counter_code);
int k;
int index=0;
for (k=0; k<5; k++)
{
PAPI_start(EventSet);
int i;
for (i=0; i<100; i++)
{
int x;
int y;
int z;
x=i+2;
y=x+i/15;
z=x/y;
}
PAPI_read(EventSet, values) ;
//printf("test number %d %lld \n",k,values[0]);
printf("%lld\n",values[0]);
PAPI_stop(EventSet, values) ;
printf("\n---------------------------------- \n");
}// end k
}
However, the output is seem to be strange for both counting and counter_code
I defined a simple event in a text file (in Linux Ubuntu OS) and set environment variable to indicate to this file. But in the code, both
PAPI_event_name_to_code("tot_ins",& counter_code); //(retvalue=-7)
and
PAPI_add_event(EventSet,counter_code); //(retvalue=-10)
return a value not equal to PAPI_OK.
any help will be appreciated.
In case someone else is lost and landing here:
I had the same issue and tried setting the environment variable
PAPI_USER_EVENTS_FILEbut it did not work in the beginning. Then I figured out that I was setting the PMU name wrong and how to get the correct PMU names. Minimal working example on my IvyBridge CPU which defines an alias forPAPI_DP_OPS:The mistake was that I used the content of the pmu_name file instead of the pmu name used by PAPI:
You can query the available PMU names with
papi_component_avail, as given in the man-pageman PAPI_derived_event_files. The filepapi_events.csv(see below) contains the preset events and all the PMU names used by PAPI. The man-page also describes the syntax of the user events file.papi_availwill show the added user event if it worked.However, I think it is buggy: e.g. the alias shows completely different numbers for the dp ops. The documentation about this feature should be improved in my opinion and the man-page for the user-defined derived event file does not contain how to specify the file.
PAPI_set_opt, as described as an alternative in the referenced paper, is currently (6.0.0.1) not supported as a way to specify the user-defined eventfile and will return an error number (error string 'null'): (from papi_preset.c)