Profiling macros

Use profiling macros to instrument the code for runtime performance profiling. More...

Macros

#define KZ_PROFILING_THIS_FUNCTION_NAME
 Gets the fully qualified, if possible, name of the enclosing function. More...
 
#define KZ_PROFILING_DEFAULT_SAMPLE_BUFFER_SIZE
 Default sample buffer size. More...
 
#define kzProfilingGetDefaultRegistry()
 Gets the reference to the default profiler registry. More...
 
#define kzProfileScope(category, scopeProfilerName)
 Profiles the execution time of a scope. More...
 
#define kzProfileScopeExtended(category, profilerRegistry, scopeProfilerName, sampleBufferSize)
 Profiles the execution time of a scope using custom profiler registry and sample buffer size. More...
 
#define kzProfileFunction(category)
 Profiles the execution time of a function. More...
 
#define kzProfileScopeWithSampler(category, profiler, samplerClass)
 Profiles the execution time of a scope using a sampler. More...
 
#define kzProfileScopeWithSamplerExtended(category, profiler, samplerClass, samplerConstructorArguments)
 Profiles the execution time of a scope using a sampler with constructor arguments. More...
 
#define KZ_LOG_DEFAULT_CATEGORY_PROFILING_STATE
 Defines profiling log category state. More...
 
#define KZ_LOG_CATEGORY_PROFILING
 The profiling log category. More...
 
#define KZ_PROFILING_DEFAULT_CATEGORY_GENERIC_STATE
 Defines generic profiling category compile time state. More...
 
#define KZ_PROFILING_CATEGORY_GENERIC
 The generic profiling category to profile code not specific to other profiling categories. More...
 
#define KZ_PROFILING_ENABLED_CATEGORY
 
#define KZ_PROFILING_DISABLED_CATEGORY
 The disabled profiling category state. More...
 
#define kzProfilingCreateCategory(compileTimeState, name, sampleBufferSize)
 Creates a new profiling category. More...
 
#define kzProfilingRegisterCategory(category, initialRuntimeState)
 Registers a new profiling category. More...
 
#define kzProfilingRegisterExportedCategory(exportImportDirective, category, initialRuntimeState)
 Registers a new profiling category that is exported/imported to/from shared library. More...
 
#define kzProfilingCategorySetRuntimeState(category, newRuntimeState)
 Sets the runtime state of a profiling category. More...
 
#define kzProfilingSetAllCategoriesRuntimState(newRuntimeState)
 Sets the runtime state of all profiling categories. More...
 
#define kzProfilingGetCategoryCompileTimeState(category)
 Gets the compile-time category state. More...
 
#define kzProfilingGetCategoryName(category)
 Gets the name of a profiling category. More...
 
#define kzProfilingGetCategorySampleBufferSize(category)
 Gets the sample buffer size of a profiling category. More...
 
#define kzProfilingGetCategoryRuntimeReference(category)
 Gets the runtime profiling category reference. More...
 
#define kzProfilingIsCategoryEnabledAtRuntime(category)
 Checks whether a profiling category is enabled at runtime. More...
 
#define kzProfilingIsCategoryEnabledAtCompileTime(category)
 Checks whether a profiling category is enabled at compile time. More...
 

Detailed Description

Use profiling macros to instrument the code for runtime performance profiling.

Kanzi profiling build

The Kanzi profiling build includes profiled Kanzi libraries. Use the Kanzi profiling build to measure the performance of different parts of Kanzi engine:

Use the KANZI_PROFILING_BUILD macro to check whether the code is compiled with the Kanzi Profiling build configuration. The KANZI_PROFILING_BUILD macro is defined for the Profiling build only.

Macro Definition Documentation

#define KZ_PROFILING_THIS_FUNCTION_NAME

Gets the fully qualified, if possible, name of the enclosing function.

If you use this macro outside of the function or method body, the behavior is undefined.

Note
Some compilers do not provide a way to obtain the name of the enclosing function. When you use such a compiler, the value of this macro is undefined.
#define KZ_PROFILING_DEFAULT_SAMPLE_BUFFER_SIZE

Default sample buffer size.

#define kzProfilingGetDefaultRegistry ( )

Gets the reference to the default profiler registry.

Returns
The reference to the default profiler registry.
#define kzProfileScope (   category,
  scopeProfilerName 
)

Profiles the execution time of a scope.

Call this macro in the beginning of the scope that you want to profile. The behavior of this macro is controlled by the profiling category you provide through the category parameter. When the compile time state of the profiling category is disabled, this macro produces no code. Otherwise, this macro creates a static profiler object of type IntervalProfiler to store profiling samples. Provide the name for that profiler through the scopeProfilerName parameter. The profiler is registered within the default profiler registry. To access the default profiler registry use the kzProfilingGetDefaultRegistry() macro.

The runtime state of the profiling category controls whether the profiler collects samples. If the runtime state of the category is disabled, the profiler does not collect samples.

If the profiler collects samples, every time the enclosing scope is entered this macro measures the time spent executing the scope and records the measurement in the sample of type #IntervalProfilerSampleData, which is after that added to the profiler.

The sample buffer size of the profiler is set to the value of the sample buffer size you assign to the profiling category through the category parameter. To get the sample buffer size assigned to the profiling category, use the kzProfilingGetCategorySampleBufferSize() macro.

Parameters
categoryThe profiling category.
scopeProfilerNameThe name of the profiler.
See also
kanzi::ProfilingCategory

Example

To profile a scope:

int profilingScope(int x, int y)
{
int c = 0;
if (x == 0 && y == 0)
{
// Profile the scope and give "scope: x==0 && y==0" name to the profiler.
kzProfileScope(KZ_PROFILING_CATEGORY_GENERIC, "scope: x==0 && y == 0");
c = 1;
}
else if (x == 0)
{
// Profile the scope. The profiler name is "x == 0, y == ?" and profiler sample buffer size is set to 100.
// The profiler is registered within default profiler registry.
c = 2;
}
return c;
}
#define kzProfileScopeExtended (   category,
  profilerRegistry,
  scopeProfilerName,
  sampleBufferSize 
)

Profiles the execution time of a scope using custom profiler registry and sample buffer size.

Call this macro in the beginning of the scope that you want to profile. The behavior of this macro is similar to the behavior of the kzProfileScope macro. This macro creates a static profiler object which is registered within the profiler registry you provide through the profilerRegistry parameter. The sample buffer size of the profiler is set to the value you provide through the sampleBufferSize parameter. The profiling category you provide through the category parameter controls the behavior of this macro in the same way as it does in the kzProfileScope macro.

Parameters
categoryThe profiling category.
profilerRegistryThe profiler registry to which you add the profiler.
scopeProfilerNameThe name of the profiler.
sampleBufferSizeThe sample buffer size of the profiler.
See also
kanzi::ProfilingCategory

Example

To profile the execution time of a scope using custom profiler registry and sample buffer size:

int profilingScope(int x, int y)
{
int c = 0;
if (x == 0 && y == 0)
{
// Profile the scope and give "scope: x==0 && y==0" name to the profiler.
kzProfileScope(KZ_PROFILING_CATEGORY_GENERIC, "scope: x==0 && y == 0");
c = 1;
}
else if (x == 0)
{
// Profile the scope. The profiler name is "x == 0, y == ?" and profiler sample buffer size is set to 100.
// The profiler is registered within default profiler registry.
c = 2;
}
return c;
}
#define kzProfileFunction (   category)

Profiles the execution time of a function.

Call this macro in the beginning of the function that you want to profile. The behavior of this macro is similar to the behavior of the kzProfileScope macro. This macro creates a static profiler object which is registered within the default profiler registry. The sample buffer size of the profiler is set to the sample buffer size assigned to the profiling category you provide through the category parameter. The name of the profiler is set to the value given by the KZ_PROFILING_THIS_FUNCTION_NAME macro.

Parameters
categoryThe profiling category.
See also
kanzi::ProfilingCategory

Example

To profile the execution time of a function:

int profilingFunction(int x, int y)
{
// Profile this function.
int c = 0;
if (x == 0 && y == 0)
{
c = 1;
}
else if (x == 0)
{
c = 2;
}
return c;
}
#define kzProfileScopeWithSampler (   category,
  profiler,
  samplerClass 
)

Profiles the execution time of a scope using a sampler.

Call this macro in the beginning of the scope that you want to profile. Use this macro when you want to create a profiler outside of the scope that you want to profile. Create the profiler before entering the scope and pass that profiler to this macro through the profiler parameter. The profiling category you provide through the category parameter controls the behavior of this macro in the same way as it does in the kzProfileScope macro. Provide the sampler class type through the samplerClass parameter. The sampler class is used to collect samples and add them to the profiler. The ProfilingScopeHelper uses the sampler class to collect samples and add them to the profiler. The local sampler object is created every time the enclosing scope is entered.

Parameters
categoryThe profiling category.
profilerThe profiler.
samplerClassThe profiling sampler class type.
See also
kanzi::ProfilingCategory

Example

To profile the execution time of a scope using a sampler:

class LoggingIntervalProfilingSampler : public IntervalProfilingSampler
{
public:
explicit LoggingIntervalProfilingSampler(string_view scopeName) : m_name(scopeName)
{
}
void start()
{
kzLogInfo(KZ_LOG_CATEGORY_PROFILING, ("Starting measuring {} scope...", m_name));
IntervalProfilingSampler::start();
}
void stop()
{
IntervalProfilingSampler::stop();
kzLogInfo(KZ_LOG_CATEGORY_PROFILING, ("Finished measuring {} scope...", m_name));
}
private:
string_view m_name;
};
int profilingWithSampler(int x, int y)
{
int c = 0;
// Create interval profiler and assign it to KZ_GENERIC_PROFILING_CATEGORY. The sample buffer size is 100.
IntervalProfilerSharedPtr profiler = IntervalProfiler::create("my profiler", kzProfilingGetCategoryRuntimeReference(KZ_PROFILING_CATEGORY_GENERIC), 100);
if (x == 0 && y == 0)
{
// Profile this scope with IntervalProfilingSampler.
kzProfileScopeWithSampler(KZ_PROFILING_CATEGORY_GENERIC, profiler, IntervalProfilingSampler);
c = 1;
}
else if (x == 0)
{
// Profile this scope with LoggingIntervalProfilingSampler, which requires to pass name of the scope to the constructor.
kzProfileScopeWithSamplerExtended(KZ_PROFILING_CATEGORY_GENERIC, profiler, LoggingIntervalProfilingSampler, ("x == 0"));
c = 2;
}
return c;
}
#define kzProfileScopeWithSamplerExtended (   category,
  profiler,
  samplerClass,
  samplerConstructorArguments 
)

Profiles the execution time of a scope using a sampler with constructor arguments.

Call this macro in the beginning of the scope that you want to profile. The behavior of this macro is similar to the behavior of kzProfileScopeWithSampler. Use this macro when the constructor of the sampler class that you provide through the samplerClass parameter requires arguments. Pass the arguments enclosed in parentheses through the samplerConstructorArguments parameter of the macro. Note that the local sampler object is created every time the enclosing scope is entered which means that the constructor arguments you provide are passed to that local object every time the scope is entered.

Parameters
categoryThe profiling category.
profilerThe profiler.
samplerClassThe profiling sampler class type.
samplerConstructorArgumentsThe sampler constructor arguments enclosed in parentheses.
See also
kanzi::ProfilingCategory

Example

To profile the execution time of a scope using a sampler with constructor arguments:

class LoggingIntervalProfilingSampler : public IntervalProfilingSampler
{
public:
explicit LoggingIntervalProfilingSampler(string_view scopeName) : m_name(scopeName)
{
}
void start()
{
kzLogInfo(KZ_LOG_CATEGORY_PROFILING, ("Starting measuring {} scope...", m_name));
IntervalProfilingSampler::start();
}
void stop()
{
IntervalProfilingSampler::stop();
kzLogInfo(KZ_LOG_CATEGORY_PROFILING, ("Finished measuring {} scope...", m_name));
}
private:
string_view m_name;
};
int profilingWithSampler(int x, int y)
{
int c = 0;
// Create interval profiler and assign it to KZ_GENERIC_PROFILING_CATEGORY. The sample buffer size is 100.
IntervalProfilerSharedPtr profiler = IntervalProfiler::create("my profiler", kzProfilingGetCategoryRuntimeReference(KZ_PROFILING_CATEGORY_GENERIC), 100);
if (x == 0 && y == 0)
{
// Profile this scope with IntervalProfilingSampler.
kzProfileScopeWithSampler(KZ_PROFILING_CATEGORY_GENERIC, profiler, IntervalProfilingSampler);
c = 1;
}
else if (x == 0)
{
// Profile this scope with LoggingIntervalProfilingSampler, which requires to pass name of the scope to the constructor.
kzProfileScopeWithSamplerExtended(KZ_PROFILING_CATEGORY_GENERIC, profiler, LoggingIntervalProfilingSampler, ("x == 0"));
c = 2;
}
return c;
}
#define KZ_LOG_DEFAULT_CATEGORY_PROFILING_STATE

Defines profiling log category state.

The profiling log category is enabled by default.

See also
KZ_LOG_CATEGORY_PROFILING
#define KZ_LOG_CATEGORY_PROFILING

The profiling log category.

Use this log category to write profiling logs only. The KZ_LOG_DEFAULT_CATEGORY_PROFILING_STATE defines the state of this log category.

#define KZ_PROFILING_DEFAULT_CATEGORY_GENERIC_STATE

Defines generic profiling category compile time state.

The generic profiling category is enabled by default.

See also
KZ_PROFILING_CATEGORY_GENERIC
#define KZ_PROFILING_CATEGORY_GENERIC

The generic profiling category to profile code not specific to other profiling categories.

The KZ_PROFILING_DEFAULT_CATEGORY_GENERIC_STATE defines the state of this category.

#define KZ_PROFILING_ENABLED_CATEGORY

The enabled profiling category state.

#define KZ_PROFILING_DISABLED_CATEGORY

The disabled profiling category state.

#define kzProfilingCreateCategory (   compileTimeState,
  name,
  sampleBufferSize 
)

Creates a new profiling category.

Use the compileTimeState parameter to set the compile-time state of the profiling category. The Profiling macros use the compile-time state of the category. The string literal you provide in name is a unique profiling category name.

Parameters
compileTimeStateThe compile-time state of the profiling category: enabled (KZ_LOG_ENABLED_CATEGORY) or disabled (KZ_LOG_DISABLED_CATEGORY).
nameUnique profiling category name. Must be string literal other than "*", which is used as wildcard name in category filter configuration.
sampleBufferSizeThe sample buffer size of the profiling category.

Example

To create and register a profiling category:

#define MY_PROFILING_CATEGORY kzProfilingCreateCategory(KZ_PROFILING_ENABLED_CATEGORY, "myCategory", KZ_PROFILING_DEFAULT_SAMPLE_BUFFER_SIZE)
#define kzProfilingRegisterCategory (   category,
  initialRuntimeState 
)

Registers a new profiling category.

To be able to use a profiling category, you must first register it. To create a profiling category use kzProfilingCreateCategory(). This macro must be called from the global namespace scope.

If the category you provide in the category parameter is disabled at compile time, this macro emits no code. The macro defines a unique type to control the runtime state of the profiling category. You must provide the initial runtime state of the category through the initialRuntimeState parameter.

Parameters
categoryThe profiling category macro to register.
initialRuntimeStateThe initial runtime state of the category: enabled (KZ_PROFILING_ENABLED_CATEGORY) or disabled (KZ_PROFILING_DISABLED_CATEGORY).

Example

To create and register a profiling category:

#define MY_PROFILING_CATEGORY kzProfilingCreateCategory(KZ_PROFILING_ENABLED_CATEGORY, "myCategory", KZ_PROFILING_DEFAULT_SAMPLE_BUFFER_SIZE)
#define kzProfilingRegisterExportedCategory (   exportImportDirective,
  category,
  initialRuntimeState 
)

Registers a new profiling category that is exported/imported to/from shared library.

To be able to use a profiling category, you must first register it. To create a profiling category use kzProfilingCreateCategory(). This macro must be called from the global namespace scope.

If the category you provide in the category parameter is disabled at compile time, this macro emits no code. The macro defines a unique type to control the runtime state of the profiling category. An export/import directive you provide in exportImportDirective parameter is added to profiling category type definition. This allows you to use profiling category registered in DLL or shared library which is linked to your application at runtime. The export/import directive is operating system and toolchain dependent. For example MSVC provides __declspec(dllexport)/__declspec(dllimport) to export/import names.

Parameters
exportImportDirectiveA directive to export/import registered category to/from shared library.
categoryThe profiling category macro to register.
initialRuntimeStateThe initial runtime state of the category: enabled (KZ_PROFILING_ENABLED_CATEGORY) or disabled (KZ_PROFILING_DISABLED_CATEGORY).

Example

To create and register an exported profiling category:

// Example export/import macro for Windows.
#ifdef USE_SHARED_LIBRARY
# ifdef COMPILE_LIBRARY_CODE
// Compiling shared library: export category to shared library.
# define EXPORT_IMPORT_API __declspec(dllexport)
# else
// Compiling user code: import category from shared library.
# define EXPORT_IMPORT_API __declspec(dllimport)
# endif
#else
// Use empty macro for static linking.
# define EXPORT_IMPORT_API
#endif
#define MY_PROFILING_CATEGORY_EXPORTED kzProfilingCreateCategory(KZ_PROFILING_ENABLED_CATEGORY, "myCategoryExported", MY_PROFILING_CATEGORY_EXPORTED)
kzProfilingRegisterExportedCategory(EXPORT_IMPORT_API, MY_PROFILING_CATEGORY_EXPORTED, KZ_PROFILING_DISABLED_CATEGORY)
#define kzProfilingCategorySetRuntimeState (   category,
  newRuntimeState 
)

Sets the runtime state of a profiling category.

If the category you provide in the category parameter is disabled at compile time, this macro emits no code.

Parameters
categoryThe profiling category macro.
newRuntimeStateNew runtime state of the category: enabled (KZ_PROFILING_ENABLED_CATEGORY) or disabled (KZ_PROFILING_DISABLED_CATEGORY).
#define kzProfilingSetAllCategoriesRuntimState (   newRuntimeState)

Sets the runtime state of all profiling categories.

Parameters
newRuntimeStateNew runtime state for all categories: enabled (KZ_PROFILING_ENABLED_CATEGORY) or disabled (KZ_PROFILING_DISABLED_CATEGORY).
#define kzProfilingGetCategoryCompileTimeState (   category)

Gets the compile-time category state.

Parameters
categoryThe profiling category macro to fetch state.
Returns
The state of category: enabled (KZ_PROFILING_ENABLED_CATEGORY) or disabled (KZ_PROFILING_DISABLED_CATEGORY).
#define kzProfilingGetCategoryName (   category)

Gets the name of a profiling category.

Parameters
categoryThe profiling category macro to fetch name.
Returns
The name of the category.
#define kzProfilingGetCategorySampleBufferSize (   category)

Gets the sample buffer size of a profiling category.

Parameters
categoryThe profiling category macro to fetch sample buffer size.
Returns
The sample buffer size of the category.
#define kzProfilingGetCategoryRuntimeReference (   category)

Gets the runtime profiling category reference.

The behavior of this macro is defined only if the category you provide in the category parameter is enabled at compile time. Otherwise the behavior of this macro is undefined.

Use this macro to fetch a reference to profiling category object, associated with the profiling category you provide in the category parameter. The profiling category object is an object of type #ProfilingCategory and is used by profiling subsystem to store of runtime category state. You can use the reference provided by this macro to get or set the runtime state of the profiling.

Parameters
categoryThe profiling category macro to fetch category runtime reference.
Returns
Reference to kanzi::ProfilingCategory.
#define kzProfilingIsCategoryEnabledAtRuntime (   category)

Checks whether a profiling category is enabled at runtime.

Use this macro to get the runtime state of the category you provide in the category parameter. If the category is disabled at compile time, this macro is evaluated to KZ_PROFILING_DISABLED_CATEGORY. Otherwise the runtime state of the category is returned.

Parameters
categoryThe profiling category macro to fetch status.
Returns
KZ_PROFILING_DISABLED_CATEGORY if the category is disabled at compile time, otherwise true/false, if profiling category is enabled/disabled at runtime.
#define kzProfilingIsCategoryEnabledAtCompileTime (   category)

Checks whether a profiling category is enabled at compile time.

Parameters
categoryThe profiling category macro to test status.
Returns
KZ_PROFILING_ENABLED_CATEGORY / KZ_PROFILING_DISABLED_CATEGORY, when profiling category is enabled / disabled.