bactria
0.0.1
The bactria library is a header-only C++14 library for profiling and tracing.
|
The bactria library is a header-only C++14 library for profiling and tracing. By annotating segments of your code with bactria's classes you can gather fine-grained information about your application's performance without introducing runtime overhead in other program parts.
bactria itself is platform-independent and provides a unified modern C++ API to the user. The profiling and/or tracing information are collected by its various plugins:
about:tracing
tool (used by AMD's ROCm).TODO: Fill this out!
The user-facing API has no dependencies. However, most plugins require toml11
to be present and additionally introduce their platform-specific dependencies (such as Score-P, CUDA or ROCm).
bactria assumes that all builds happen out-of-source. The easiest way to achieve this is to create a build
directory in bactria's top-level directory:
bactria uses CMake (>=3.18) as a build system. On top of the common CMake build options (such as the build type) it supports the following configuration switches:
bactria_BUILD_DOCUMENTATION
– Build the Doxygen documentation. Default: ON
.bactria_BUILD_EXAMPLES
– Build the examples (see the examples
folder). Default: ON
.bactria_CUDA_PLUGINS
– Build the CUDA ecosystem plugins. Default: OFF
bactria_JSON_PLUGINS
– Build the JSON-based plugins. Default: ON
bactria_SYSTEM_JSON
– Use your local installation of the nlohnmann-json library. If set to OFF
, bactria will attempt to download the library to its build directory. Default: ON
.bactria_ROCM_PLUGINS
– Build the ROCm ecosystem plugins. Default: OFF
.bactria_SCOREP_PLUGINS
– Build the Score-P plugins. Default: OFF
.bactria_STDOUT_PLUGINS
– Build the stdout
plugins. Default: ON
.bactria_SYSTEM_FMT
– Use your local installation of {fmt}
if the stdout
plugins are being built. If set to OFF
, bactria will attempt to download the library to its build directory. Default: ON
.bactria_SYSTEM_TOML11
– Use your local installation of toml11. If set to OFF
, bactria will attempt to download the library to its build directory. Default: ON
.The following example configures the build system for building the Doxygen documentation, the examples and the plugins for CUDA, JSON, Score-P and stdout
in Release
mode:
If the previous step was successful all that is left to do is invoke the actual build command:
After a successful bactria build the contents of your build
directory will look similar to this structure (Visual Studio and XCode builds may have another intermediate directory between build
and the subdirectories here):
You should be interested in the contents of examples
and src
. In the subdirectories of the examples
folder you will find executables which already have built-in bactria support. In the subdirectories of the src
folder you will find the plugins that were built according to your configuration:
Switch to the directory with the built simpleLoop
example:
If you just execute the program without any further configuration you will notice that there are no additional output files produced. This is a design principle: If you do not want to use a certain aspect of bactria you do not have to! Internally, bactria will disable this functionality if no plugin was selected at runtime.
To enable bactria's plugins you have to set one (or more) of the following environment variables to the path of your desired plugin:
After the program execution you should see some additional files in the directory that have not been present before. These are the files you can now load into your favourite analysis / profiling tools for further examination.
In the next sections we will explain the concepts behind metrics
, ranges
and reports
.
Before you can use bactria you have to initialize the library. This is done by creating a Context
(once per process) and keeping it alive until you no longer require any functionality from bactria. The Context
takes care of loading your selected plugin(s) into memory so you can make use of bactria's user API. The easiest way for managing a bactria Context
is to create it at the beginning of main
and keep it alive until the program stops:
Note that the context is wrapped into a try
/catch
block. Should any internal errors occur in bactria's user-facing parts a std::runtime_error
will be thrown.
bactria's ranges are a useful tool if you want to highlight / visualize certain events and time spans (= ranges) in your application code. This gives you a high-level view onto your program's behaviour and can help you with choosing the correct code segments to analyse in more detail.
Event
s are single points in time and are simply triggered / fire
d in the application code.Range
s are time spans and are start
ed and stop
ped.Event
s and Range
s can be assigned to a Category
. Through the configuration file you can filter out all Event
s and Range
s part of a specific Category
.Event
s and Range
s can freely overlap / be nested in any way you feel necessary. This is how it looks like in code:
As you may have noticed we have supplied a color to the range / event constructor. Some plugins support custom colors to enhance the visualizer output (this depends on vendor APIs and is therefore not supported by all available plugins). You can either use one of bactria's numerous pre-defined colors (see Colors.hpp) or supply your own color in ARGB format:
Once you have an idea of where your program spends most of its time you might want to optimize these portions. In order to find the major bottlenecks it is useful to look at certain metrics like hardware counters, a more detailed profiling, call stacks, and so on. Plugins implementing bactria's metrics
functionality are built on top of various vendors' APIs dedicated to this purpose. By using bactria's metrics
API you can make use of these APIs in a portable way.
In the metrics
API the following classes are available:
Sector
s are used as annotations in your code and enable the detailed collection of metrics by your ecosystem's performance tools.Tag
s are a special kind of metadata that some plugins can make use of. By default, all Sector
s are assigned the Generic
tag. Some plugins understand additional information supplied by other Tag
s, such as Function
, Loop
, Body
, and so on, to provide you with more detailed results.Phase
s are used to group Sector
s (possibly in different scopes) into logical program phases. Some performance tools can make use of this information to provide you with an analysis of these logical segments.Both Sector
s and Phase
s follow a stack-based / LIFO-based programming approach. This means that they have to be correctly nested and cannot overlap freely (in contrast to the ranges
API).
Example:
Sometimes the metrics collected by the various vendor-specific plugins are not enough. For this case bactria provides the reports
API which enables you to save key-value pairs (where key
is a std::string
and value
an arithmetic type or a std::string
). To do this, you first create a IncidentRecorder
and use it to create Incident
s (the key-value pairs). Once your recording is complete you can submit a Report
(which matches the output file generated by the plugin):
This work was partially funded by the Center of Advanced Systems Understanding (CASUS) which is financed by Germany's Federal Ministry of Education and Research (BMBF) and by the Saxon Ministry for Science, Culture and Tourism (SMWK) with tax funds on the basis of the budget approved by the Saxon State Parliament.
This free software is licensed unter the EUPL v1.2. Please refer to the LICENSE
file in the top-level source code directory for the concrete details of this licence.