Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ CTRACK is a powerful tool that can be seamlessly integrated into both developmen
## Features

- Single header file
- No dependencies
- No dependencies (optional tbb for non msvc to use paralell result calculation)
- Easy to use (just 1 line per function you want to track)
- Minimal overhead (can record tens of millions events per second)
- Optimized for multi-threaded environments
Expand Down Expand Up @@ -168,6 +168,9 @@ CTRACK is a header-only library, which means you can start using it by simply in

This method is straightforward and doesn't require any additional setup or build process.

Note: If you are using a compiler which needs TBB for C++ standard parallel algorithms, you need to link to -ltbb. You can always fall back to sequential result calculation by setting
CTRACK_DISABLE_EXECUTION_POLICY. The recording will be unchanged, but the printing/calculating of the stats will be a bit slower.

### 2. CMake Package

For projects using CMake, CTRACK can be installed and used as a CMake package. This method provides better integration with your build system and makes it easier to manage dependencies.
Expand All @@ -191,6 +194,11 @@ To use CTRACK as a CMake package:
target_link_libraries(your_target PRIVATE CTRACK::CTRACK)
```

Note: If you are using a compiler which needs TBB for C++ standard parallel algorithms, you need to link to tbb.
```target_link_libraries( your_target PRIVATE TBB::tbb ) ```
You can always fall back to sequential result calculation by setting
CTRACK_DISABLE_EXECUTION_POLICY. The recording will be unchanged, but the printing/calculating of the stats will be a bit slower.

For more detailed examples of how to use CTRACK with CMake, please refer to the `examples` directory in the CTRACK repository.

Choose the installation method that best fits your project's needs and structure. Both methods provide full access to CTRACK's features and capabilities.
Expand Down
31 changes: 31 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,41 @@
option(DISABLE_PAR "Disable parallel processing" OFF)
if(NOT MSVC AND NOT DISABLE_PAR)
# For other compilers, check for TBB
find_package(TBB QUIET)
if(TBB_FOUND)
message(STATUS "TBB found. Enabling parallel execution.")
else()
message(STATUS "TBB not found. Disabling parallel execution.")
set(DISABLE_PAR ON)
endif()
elseif(DISABLE_PAR)
message(STATUS "DISABLE_PAR set. Disabling parallel execution.")
endif()


# Function to enable parallel execution on non msvc
function(enable_parallel_execution target)
if(DISABLE_PAR)
target_compile_definitions(${target} PRIVATE CTRACK_DISABLE_EXECUTION_POLICY)
elseif(NOT MSVC)
target_link_libraries(${target} PRIVATE TBB::tbb)
endif()
endfunction()

# Create executables for each example
add_executable(basic_singlethreaded basic_singlethreaded.cpp)
add_executable(multithreaded_prime_counter multithreaded_prime_counter.cpp)
add_executable(ctrack_overhead_test ctrack_overhead_test.cpp)
add_executable(high_variance_pi_estimation high_variance_pi_estimation.cpp)
add_executable(complex_multithreaded_puzzle complex_multithreaded_puzzle.cpp)

#check for paralell
enable_parallel_execution(basic_singlethreaded)
enable_parallel_execution(multithreaded_prime_counter)
enable_parallel_execution(ctrack_overhead_test)
enable_parallel_execution(high_variance_pi_estimation)
enable_parallel_execution(complex_multithreaded_puzzle)

# Link the ctrack library to each example
target_link_libraries(basic_singlethreaded PRIVATE ctrack)
target_link_libraries(multithreaded_prime_counter PRIVATE ctrack)
Expand Down
38 changes: 23 additions & 15 deletions include/ctrack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,20 @@
#include <algorithm>
#include <set>
#include <numeric>
#ifndef CTRACK_DISABLE_EXECUTION_POLICY
#include <execution>
#endif
#include <vector>
#include <iomanip>
#include <fstream>
#include <filesystem>
#include <sstream>
#include <atomic>
#include <cmath>

#define CTRACK_VERSION_MAJOR 1
#define CTRACK_VERSION_MINOR 0
#define CTRACK_VERSION_PATCH 0
#define CTRACK_VERSION_PATCH 1

// Helper macro to convert a numeric value to a string
#define STRINGIFY(x) #x
Expand All @@ -44,14 +48,18 @@
namespace ctrack {

inline namespace CTRACK_VERSION_NAMESPACE {

#ifndef CTRACK_DISABLE_EXECUTION_POLICY
constexpr auto execution_policy = std::execution::par_unseq;
#define OPT_EXEC_POLICY execution_policy,
#else
#define OPT_EXEC_POLICY
#endif

template<typename T, typename Field>
auto sum_field(const std::vector<T>& vec, Field T::* field) {
using FieldType = std::decay_t<decltype(std::declval<T>().*field)>;
return std::transform_reduce(
execution_policy,
OPT_EXEC_POLICY
vec.begin(), vec.end(),
FieldType{},
std::plus<>(),
Expand All @@ -63,7 +71,7 @@ namespace ctrack {
auto sum_squared_field(const std::vector<T>& values, Field T::* field) {
using FieldType = std::decay_t<decltype(std::declval<T>().*field)>;
return std::transform_reduce(
execution_policy,
OPT_EXEC_POLICY
values.begin(), values.end(),
FieldType{},
std::plus<>(),
Expand All @@ -76,7 +84,7 @@ namespace ctrack {
template<typename T, typename Field>
double calculate_std_dev_field(std::vector<T>& values, Field T::* field, const double mean) {
double res = std::transform_reduce(
execution_policy,
OPT_EXEC_POLICY
values.begin(), values.end(),
0.0,
std::plus<>(),
Expand Down Expand Up @@ -105,7 +113,7 @@ namespace ctrack {

template <typename StructType, typename MemberType>
void order_pointer_vector_by_field(std::vector<StructType*>& vec, MemberType StructType::* member, bool asc = true) {
std::sort(execution_policy, vec.begin(), vec.end(),
std::sort(OPT_EXEC_POLICY vec.begin(), vec.end(),
[member, asc](const StructType* a, const StructType* b) {
if (asc)
return (a->*member) < (b->*member);
Expand All @@ -117,7 +125,7 @@ namespace ctrack {
template <typename T>
size_t countAllEvents(const std::deque<std::vector<T>>& events) {
return std::transform_reduce(
execution_policy,
OPT_EXEC_POLICY
events.begin(), events.end(),
size_t(0),
std::plus<>(),
Expand Down Expand Up @@ -393,7 +401,7 @@ namespace ctrack {
std::vector<Simple_Event> simple_events{};
simple_events.resize(events.size());
std::transform(
execution_policy,
OPT_EXEC_POLICY
events.begin(), events.end(),
simple_events.begin(),
[](const Event& event) {
Expand All @@ -409,7 +417,7 @@ namespace ctrack {
std::vector<Simple_Event> simple_events{};
simple_events.resize(events.size());
std::transform(
execution_policy,
OPT_EXEC_POLICY
events.begin(), events.end(),
simple_events.begin(),
[](const Event* event) {
Expand Down Expand Up @@ -482,7 +490,7 @@ namespace ctrack {
return;

auto all_events_simple = create_simple_events(all_events);
std::sort(execution_policy, all_events_simple.begin(), all_events_simple.end(), cmp_simple_event_by_duration_asc);
std::sort(OPT_EXEC_POLICY all_events_simple.begin(), all_events_simple.end(), cmp_simple_event_by_duration_asc);
all_cnt = static_cast<unsigned int> (all_events_simple.size());
const double factor = (1.0 / static_cast<double>(all_cnt));

Expand Down Expand Up @@ -540,19 +548,19 @@ namespace ctrack {

auto center_child_events_simple = load_child_events_simple(center_events_simple, events_map, child_graph);

std::sort(execution_policy, center_events_simple.begin(), center_events_simple.end(), cmp_simple_event_by_start_time_asc);
std::sort(OPT_EXEC_POLICY center_events_simple.begin(), center_events_simple.end(), cmp_simple_event_by_start_time_asc);
center_grouped = sorted_create_grouped_simple_events(center_events_simple);
center_time_active = sum_field(center_grouped, &Simple_Event::duration);

std::sort(execution_policy, center_child_events_simple.begin(), center_child_events_simple.end(), cmp_simple_event_by_start_time_asc);
std::sort(OPT_EXEC_POLICY center_child_events_simple.begin(), center_child_events_simple.end(), cmp_simple_event_by_start_time_asc);
auto center_child_events_grouped = sorted_create_grouped_simple_events(center_child_events_simple);
center_time_active_exclusive = center_time_active - sum_field(center_child_events_grouped, &Simple_Event::duration);

std::sort(execution_policy, all_events_simple.begin(), all_events_simple.end(), cmp_simple_event_by_start_time_asc);
std::sort(OPT_EXEC_POLICY all_events_simple.begin(), all_events_simple.end(), cmp_simple_event_by_start_time_asc);
all_grouped = sorted_create_grouped_simple_events(all_events_simple);
all_time_active = sum_field(all_grouped, &Simple_Event::duration);

std::sort(execution_policy, all_child_events_simple.begin(), all_child_events_simple.end(), cmp_simple_event_by_start_time_asc);
std::sort(OPT_EXEC_POLICY all_child_events_simple.begin(), all_child_events_simple.end(), cmp_simple_event_by_start_time_asc);
auto all_child_events_grouped = sorted_create_grouped_simple_events(all_child_events_simple);
all_time_active_exclusive = all_time_active - sum_field(all_child_events_grouped, &Simple_Event::duration);
}
Expand Down Expand Up @@ -721,7 +729,7 @@ namespace ctrack {
}
}

std::sort(execution_policy, grouped_events.begin(), grouped_events.end(), cmp_simple_event_by_start_time_asc);
std::sort(OPT_EXEC_POLICY grouped_events.begin(), grouped_events.end(), cmp_simple_event_by_start_time_asc);
auto all_grouped = sorted_create_grouped_simple_events(grouped_events);
sum_time_active_exclusive = sum_field(all_grouped, &Simple_Event::duration);

Expand Down