PAPIC:Multiplexing
From PAPIDocs
Jump to: navigation, search

Contents

Multiplexing

Multiplexing allows more events to be counted than can be supported by the hardware. When a microprocessor has a limited number of hardware counters, a large application with many hours of run time may require days or weeks of profiling in order to gather enough information on which to base a performance analysis. Multiplexing overcomes this limitation by subdividing the usage of the counter hardware over time (timesharing) among a large number of performance events.

Using PAPI with Multiplexing

Initialization of Multiplex Support

Multiplex support in the PAPI library can be enabled and initialized by calling the following low-level function:

C:
 
int PAPI_muliplex_init()
Fortran:
 
PAPIF_multiplex_init(check)

The above function sets up the internal structures to allow more events to be counted than there are physical counters. It does this by timesharing the existing counters at some loss in precision. This function should be used after calling PAPI_library_init. After this function is called, the user can proceed to use the normal PAPI routines. It should be also noted that applications that make no use of multiplexing should not call this function.

On success, this function returns PAPI_OK and on error, a non-zero error code is returned.

For a code example, see the next section.

Converting an EventSet into a Multiplexed EventSet

A standard event set can be converted to a multiplexed event set by the calling the following low-level functions:

C:
 
int PAPI_set_multiplex(int *EventSet);
int PAPI_assign_eventset_component(int *EventSet, int *cidx);
Fortran:
 
PAPIF_set_multiplex(EventSet, check)
PAPIF_assign_eventset_component(EventSet, cidx, check)

Arguments

EventSet an integer handle for a PAPI event set as created by PAPI_create_eventset
cidx an integer value for a component index; by convention the CPU is always 0
check an error return value for Fortran

The above functions are used to convert a standard PAPI event set into an event set capable of handling multiplexed events. An eventset must first be created with a call to PAPI_create_eventset. This eventset is not bound to a component until either an event is added to it with PAPI_add_event(s) or by calling PAPI_assign_eventset_component. PAPI_set_multiplex cannot be called until after the eventset is bound to a component. Events can be added to an event set either before or after converting it into a multiplexed set, but the conversion must be done prior to calling PAPI_start and using it as a multiplexed set.

Example

In the following code example, PAPI_assign_eventset_component and PAPI_set_multiplex are used to convert a standard event set into a multiplexed event set:

 
#include <papi.h>
 
int retval, i, EventSet = PAPI_NULL, max_to_add = 6, j = 0;
long long *values;
const PAPI_preset_info_t *pset;
 
main()
{
  /* Initialize the PAPI library */
  retval = PAPI_library_init(PAPI_VER_CURRENT);
  if (retval != PAPI_VER_CURRENT) handle_error(1);
 
  /* Enable and initialize multiplex support */
  retval = PAPI_multiplex_init();
  if (retval != PAPI_OK) handle_error(retval);
 
 /* Create an EventSet */
  retval = PAPI_create_eventset(&EventSet);
  if (retval != PAPI_OK) handle_error(retval);
 
 /* Assign it to the CPU component */
  retval = PAPI_assign_eventset_component(EventSet, 0);
  if (retval != PAPI_OK) handle_error(retval);
 
 /* Convert the EventSet to a multiplexed event set */
  retval = PAPI_set_multiplex(EventSet);
  if (retval != PAPI_OK) handle_error(retval);
 
  for (i=0;i<PAPI_MAX_PRESET_EVENTS;i++)
  {
    if ((PAPI_query_event (i | PAPI_PRESET) == PAPI_OK)
    && ((i | PAPI_PRESET) != PAPI_TOT_CYC))
     {
     	retval = PAPI_add_event(&EventSet, pset->event_code);
        if (retval != PAPI_OK) handle_error(retval);
 
        if (++j >= max_to_add)
            break;
     }
  }
 
  values = (long_long *)malloc(max_to_add*sizeof(long_long));
  if (values == NULL)
    handle_error(1);
 
  /* Start counting events */
  retval = PAPI_start(EventSet);
  if (retval != PAPI_OK) handle_error(retval);
}

On success, both functions return PAPI_OK and on error, a non-zero error code is returned.

For more code examples, see ctests/multiplex1.c and ctests/multiplex2.c.

Multiplexng Issues

The following are some issues concerning multiplexing that the PAPI user should be aware of:

Hardware multiplexing is not supported by all platforms. On those platforms where it is supported, PAPI takes advantage of it. Otherwise, PAPI implements software multiplexing through the use of a high-resolution interval timer. For more information on which platforms support hardware or software multiplexing, see Appendix H.

Multiplexing unavoidably incurs a small amount of overhead when switching events. In addition, no single event is measured for the full analysis time. These factors can adversely affect the precision of reported counter values. In other words, the more events that are multiplexed, the more likely that the results will be statistically skewed. The amount of time spent in the measured regions should be greater than the multiplexing time slice times the number of events measured in order to get acceptable results.

The default time slice for multiplexing is currently set at 100000 microseconds. Occasionally this setting can cause a resonant situation in the code in which a given pattern repeats at the same frequency that timers are switched out. This can by addressed by changing the time slice setting by calling PAPI_set_opt with the PAPI_DEF_MPX_USEC option.

To prevent naïve use of multiplexing by the novice user, the high level API can only access those events countable simultaneously by the underlying hardware, unless a low level function has been called to explicitly enable multiplexing.