Wiki

Clone wiki

papi / PAPI-Overflow

Overflow

An overflow happens when the number of occurrences of a particular hardware event exceeds a specified threshold. PAPI provides the ability to call user-defined handlers when an overflow occurs. This can be done in hardware, if the processor generates an interrupt signal when the counter reaches a specified value, or in software, by setting up a high-resolution interval timer and installing a timer interrupt handler. For software based overflow, PAPI compares the current counter value against the threshold every time the timer interrupt occurs. If the current value exceeds the threshold, then the user’s handler is called from within the signal context with some additional arguments. These arguments allow the user to determine which event overflowed, by how much it overflowed, and at what location in the source code the overflow occurred.

Using the same mechanism as for user programmable overflow, PAPI also guards against register precision overflow of counter values. Each counter can potentially be incremented multiple times in a single clock cycle. This fact combined with increasing clock speeds and the small dynamic range of some of the physical counters means that an overflow is likely to occur on platforms where 64-bit counters are not supported in hardware or by the operating system. In those cases, the PAPI implements 64-bit counters in software using the same mechanism that handles overflow dispatch.

Beginning Overflows in Event Sets

An event set can begin registering overflows by calling the following low-level function:

PAPI_overflow(EventSet, EventCode, threshold, flags, handler)

Arguments

  • EventSet -- a reference to the event set to use
  • EventCode -- the event to be used for overflow detection
  • threshold -- the overflow threshold value to use
  • flags -- bit map that controls the overflow mode of operation. The only currently valid setting is PAPI_OVERFLOW_FORCE_SW, which overrides the default hardware overflow setting on a platform that supports hardware overflow.
  • handler -- the handler function to call upon overflow

This function marks a specific EventCode in an EventSet to generate an overflow signal after every threshold events are counted. Multiple events within an event set can be programmed to overflow by making successive calls to this function, but only a single overflow handler can be registered. To turn off overflow for a specific event, call PAPI_overflow with EventCode set to the desired event and threshold set to zero.

Overflow Handler

The handler function is a user-supplied callback routine that performs whatever special processing needed to handle the overflow interrupt, including sorting multiple overflowing events from each other. It must conform to the following prototype:

PAPI_overflow_handler(EventSet, address, overflow_vector, void *context)

Arguments

  • EventSet -- a reference to the event set in use
  • address -- the address of the program counter when the overflow occurred
  • overflow_vector -- a 64-bit vector that specifies which counter(s) generated the overflow. Bit 0 corresponds to counter 0. The handler should be able to deal with multiple overflow bits per call if more than one event may be set to overflow.
  • context -- a platform dependent structure containing information about the state of the machine when the overflow occurred. This structure is provided for completeness, but can generally be ignored by most users.

Example

In the following code example, PAPI_overflow is used to mark PAPI_TOT_INS in order to generate an overflow signal after every 100,000 counted events:

#include <papi.h>
#include <stdio.h>

#define THRESHOLD  100000

int total = 0;      /* total overflows */

void handler(int EventSet, void *address, long_long overflow_vector, void *context)
{
fprintf(stderr, "handler(%d) Overflow at %p! vector=0x%llx\n",
    EventSet, address, overflow_vector);
    total++;
}

main()
{
    int retval, EventSet = PAPI_NULL;

    /* Initialize the PAPI library */
    retval = PAPI_library_init(PAPI_VER_CURRENT);
    if (retval != PAPI_VER_CURRENT)
           handle_error(1);

    /* Create the EventSet */
    if (PAPI_create_eventset(&EventSet) != PAPI_OK)
           handle_error(1);

    /* Add Total Instructions Executed to our EventSet */
    if (PAPI_add_event(EventSet, PAPI_TOT_INS) != PAPI_OK)
           handle_error(1);

    /* Call handler every 100000 instructions */
    retval = PAPI_overflow(EventSet, PAPI_TOT_INS, THRESHOLD, 0, handler);
    if (retval != PAPI_OK)
           handle_error(1);

    /* Start counting */
    if (PAPI_start(EventSet) != PAPI_OK)
           handle_error(1);
}

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

For more code examples, see ctests/overflow.c, ctests/overflow_twoevents.c or ctests/overflow_pthreads.c in the papi source distribution.

Updated