A modern, header-only C++ wrapper for the ITT API instrumentation library. The wrapper provides RAII-based scoped helpers and type-safe C++ abstractions over the existing C API.
| API | C++ Wrapper |
|---|---|
| String Handle | ittapi::StringHandle |
| Domain | ittapi::Domain |
| Task | ittapi::ScopedTask, Domain::task_begin() / Domain::task_end() |
| Region | ittapi::ScopedRegion |
| Frame | ittapi::ScopedFrame |
| Collection Control | ittapi::pause(), ittapi::resume(), ittapi::ScopedPause |
| Thread Naming | ittapi::set_thread_name() |
ittnotify static C-libraryUse the umbrella header to get the full API:
#include <ittapi.hpp>
Or include individual headers:
#include <ittapi_domain.hpp> #include <ittapi_task.hpp> #include <ittapi_collection_control.hpp>
#include <ittapi.hpp> #include <chrono> #include <thread> int main() { ittapi::set_thread_name("main"); ittapi::Domain domain{"example.task"}; ittapi::StringHandle task_name{"process"}; ittapi::pause(); ittapi::resume(); { auto task = domain.task(task_name); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } return 0; }
find_package(ittapi CONFIG REQUIRED) target_link_libraries(my_app PRIVATE ittapi::cxx)
The ittapi::cxx target is an INTERFACE library that transitively links the existing ittnotify static library and adds the C++ wrapper include directories.
g++ -std=c++17 -O2 \ -I<ittapi-install-prefix>/include \ app.cpp \ <ittapi-install-prefix>/lib/libittnotify.a \ -ldl -pthread \ -o app
From the repository root:
cmake -B build -DCMAKE_BUILD_TYPE=Release -DITT_API_CPP_SUPPORT=ON cmake --build build
The ITT_API_CPP_SUPPORT option is OFF by default.
You can also build with the build script:
python buildall.py --cpp
Tests are registered inside the cpp/ subdirectory. After building:
ctest --test-dir build/cpp --output-on-failure
StringHandle objects for task/region names used in hot paths. The StringHandle overloads pass a raw pointer with no locking — this is the zero-overhead path.// Do this once at startup: ittapi::StringHandle name{"compute"}; // Then in hot code: auto task = domain.task(name); // no allocation, no lock
string_view overloads are convenient but allocate a std::string on cache miss and acquire a lock in the C library. Use them for setup or infrequent tasks, not tight loops.Domain objects once and reuse them. Domain creation is a global lookup — store them as class members or globals, not as function locals called repeatedly.ittapi::pause() — Pause collection.ittapi::resume() — Resume collection.ittapi::set_thread_name(std::string_view name) — Set the current thread's name.ittapi::StringHandleLightweight wrapper around __itt_string_handle*.
ittapi::StringHandle h{"my_handle"}; h.valid(); // true if handle was created h.get(); // underlying __itt_string_handle*
ittapi::DomainLightweight wrapper around __itt_domain* with convenience factories.
ittapi::Domain d{"my.domain"}; auto task = d.task("task_name"); // returns ScopedTask (RAII) auto region = d.region("region_name"); // returns ScopedRegion auto frame = d.frame(); // returns ScopedFrame d.task_begin("work"); // manual task begin (simple stack-based task) d.task_end(); // manual task end __itt_id id = __itt_id_make(nullptr, 1); d.task_begin("overlapped", id, __itt_null); // manual task begin (overlapped task) d.task_end(id); // manual task end by ID
ittapi::ScopedTaskRAII wrapper for task begin/end. Use domain.overlapped_task() to create an overlapped task (tasks that can end in any order). Each overlapped task instance gets a unique __itt_id derived from its object address. The id() method returns this ID.
// Simple task { auto task = domain.task("work"); // ... do work ... task.end(); // optional early end (idempotent) } // destructor ends task if still active
Overlapped tasks — use overlapped_task(), optionally pass a parent ID:
{ auto parent = domain.overlapped_task("parent"); // overlapped, no parent auto child = domain.overlapped_task("child", parent.id()); // overlapped, child of parent parent.end(); // end parent task while child is still running child.end(); // child task ends }
For manual (non-RAII) control:
domain.task_begin("work"); // ... do work ... domain.task_end(); // overlapped tasks: __itt_id id = __itt_id_make(nullptr, 1); domain.task_begin("overlapped_work", id, __itt_null); // ... do work ... domain.task_end(id);
ittapi::ScopedRegionRAII wrapper for region begin/end.
ittapi::ScopedFrameRAII wrapper for frame begin/end. Supports explicit timestamp submission.
ittapi::ScopedFrame::submit(domain.get(), begin_ts, end_ts);
ittapi::ScopedPauseRAII wrapper for pause/resume. Constructor pauses, destructor resumes.
{ ittapi::ScopedPause sp; // collection is paused sp.resume_now(); // optional early resume }