HPX - High Performance ParalleX


Providing Performance Counter Data

HPX provides several ways to provide your own data as a performance counter. This has the benefit of exposing additional, possibly application specific information using the existing Performance Counter framework, unifying the process of gathering data about your application.

An application that wants to provide counter data can implement a Performance Counter to provide the data. When a consumer queries performance data, the HPX runtime system calls the provider to collect the data. The runtime system uses an internal registry to determine which provider to call.

Exposing Performance Counter Data using a Simple Function

The simplest way to expose arbitrary numeric data is to write a function which then will be called whenever a consumer queries this counter. Currently, this type of Performance Counter can only be used to expose integer values. The expected signature of this function is:

boost::int64_t some_performance_data();

For instance, here is such a function returning how often it was invoked:

// The atomic variable 'counter' ensures the thread safety of the counter.
boost::atomic<boost::int64_t> counter(0);

boost::int64_t some_performance_data()
    return ++counter;

This example function exposes a linearly increasing value as our performance data. The value is incrememnted on each invocation, e.g. each time a consumer requests the counter data of this Performance Counter.

The next step in exposing this counter to the runtime system is to register the function as a new raw counter type using the HPX API function hpx::performance_counters::install_counter_type. A counter type represents certain common characteristics of counters, like their counter type name, and any associated description information. The following snippet shows an example of how to register the function some_performance_data which is shown above for a counter type named "/test/data". This registration has to be executed before any consumer instantiates and queries an instance of this counter type.

#include <hpx/include/performance_counters.hpp>

void register_counter_type()
    // Call the HPX API function to register the counter type.
        "/test/data",                                   // counter type name
        &some_performance_data,                         // function providing counter data
        "returns a linearly increasing counter value"   // description text (optional)
        ""                                              // unit of measure (optional)

Now it is possible to instantiate a new counter instance based on the naming scheme "/test{locality#<*>/total}/data", where <*> is a zero based integer index indentifying the locality for which the counter instance should be accessed. The function install_counter_type enables to instantiate exactly one counter instance for each locality. Repeated requests to instantiate such a counter will return the same instance, e.g. the instance created for the first request.

If this counter should be accessible using the standard HPX command line options, the registration has to be performed during application startup, before hpx_main is executed. The best way to achieve this is to register a HPX startup function using the API function hpx::register_startup_function before calling hpx::init to initialize the runtime system:

int main(int argc, char* argv[])
    // By registering the counter type we make it available to any consumer
    // creating and querying an instance of the type "/test/data".
    // This registration should be performed during startup. We register the
    // function 'register_counter_type' to be executed as an HPX thread right
    // before hpx_main will be executed.

    // Initialize and run HPX.
    return hpx::init(argc, argv);

Please see the code in simplest_performance_counter.cpp for a full example demonstrating this functionality.