All Projects → manvis → IYFThreading

manvis / IYFThreading

Licence: other
A C++11 thread pool and profiler

Programming Languages

C++
36643 projects - #6 most used programming language
CMake
9771 projects

Projects that are alternatives of or similar to IYFThreading

Yii2 Debug
Debug Extension for Yii 2
Stars: ✭ 179 (+645.83%)
Mutual labels:  profiler
Cloud Ops Sandbox
Cloud Operations Sandbox is an open source tool that helps practitioners to learn Service Reliability Engineering practices from Google and apply them on their cloud services using Cloud Operations suite of tools.
Stars: ✭ 191 (+695.83%)
Mutual labels:  profiler
ThreadPool2
Lightweight, Generic, Pure C++11 ThreadPool
Stars: ✭ 28 (+16.67%)
Mutual labels:  thread-pool
Nlp profiler
A simple NLP library allows profiling datasets with one or more text columns. When given a dataset and a column name containing text data, NLP Profiler will return either high-level insights or low-level/granular statistical information about the text in that column.
Stars: ✭ 181 (+654.17%)
Mutual labels:  profiler
Myperf4j
High performance Java APM. Powered by ASM. Try it. Test it. If you feel its better, use it.
Stars: ✭ 2,281 (+9404.17%)
Mutual labels:  profiler
Liveprof
A performance monitoring system for running on live sites
Stars: ✭ 206 (+758.33%)
Mutual labels:  profiler
Hotspot
The Linux perf GUI for performance analysis.
Stars: ✭ 2,415 (+9962.5%)
Mutual labels:  profiler
profiler
Continuous profiling based on pprof
Stars: ✭ 221 (+820.83%)
Mutual labels:  profiler
Coz
Coz: Causal Profiling
Stars: ✭ 2,719 (+11229.17%)
Mutual labels:  profiler
Pyinstrument
🚴 Call stack profiler for Python. Shows you why your code is slow!
Stars: ✭ 3,870 (+16025%)
Mutual labels:  profiler
Startuptime.vim
Breakdown Vim's --startuptime output
Stars: ✭ 180 (+650%)
Mutual labels:  profiler
Spf4j
Simple performance framework for java
Stars: ✭ 184 (+666.67%)
Mutual labels:  profiler
Androidgodeye
An app performance monitor(APM) , like "Android Studio profiler", you can easily monitor the performance of your app real time in browser
Stars: ✭ 2,430 (+10025%)
Mutual labels:  profiler
Unityheapexplorer
A Memory Profiler, Debugger and Analyzer for Unity 2019.3 and newer.
Stars: ✭ 179 (+645.83%)
Mutual labels:  profiler
Gecko-Profiler-Addon
(deprecated) Addon to control the Gecko Built-in Profiler
Stars: ✭ 20 (-16.67%)
Mutual labels:  profiler
Tracy
C++ frame profiler
Stars: ✭ 3,115 (+12879.17%)
Mutual labels:  profiler
Aprof
Java memory allocation profiler
Stars: ✭ 200 (+733.33%)
Mutual labels:  profiler
super-workers
🐴 Distribute load on front-end via parallelism
Stars: ✭ 93 (+287.5%)
Mutual labels:  thread-pool
tensorflow profiling
Scripts with example usage of tensorflow profiler
Stars: ✭ 85 (+254.17%)
Mutual labels:  profiler
Router.cr
Minimum High Performance Middleware for Crystal Web Server.
Stars: ✭ 231 (+862.5%)
Mutual labels:  profiler

The IYFThreading library

This is a header only C++11 (and later) library that contains a thread pool and a profiler. It is licensed under the 3-clause BSD license and only depends on the standard library. Last but not least, when testing, this library is built with -fsanitize=thread and the sanitizer does not detect any invalid behaviour.

Some components of this library may be used independently of one another. Here's a list of what does what:

  1. ThreadPool.hpp: independent of other headers, unless you enable thread pool profiling. The thread pool distributes assigned work to multiple worker threads. It supports barriers (blocking a thread until specified tasks complete) and tasks with or without returned results.
  2. ThreadProfiler.hpp: Depends on the ThreadProfilerSettings header. A lightweight header that contains function definitions and macros used for profiling. It enables you to record the durations of specified scopes. Moreover, even if profiling is disabled, you may use some of the macros defined in this header to assign names to your threads and to retrieve constant sequential zero-based IDs for them as well.
  3. ThreadProfilerCore.hpp: depends on the Spinlock and ThreadProfilerSettings headers. Heavy, but you only need to include it in two cases:
    1. the cpp file will contain the implementation (that is, IYFT_THREAD_PROFILER_IMPLEMENTATION will be defined in it);
    2. the functions in the file will need to retrieve, process and/or draw the recorded results using Ocornut's Dear ImGui.
  4. ThreadProfilerSettings.hpp: customizable settings and values, specific to your project. Make sure to not accidentally overwrite this file when updating this library.
  5. Spinlock.hpp: a really basic atomic_flag based spinlock that anyone can write in a minute. Independent of other headers.

This library is still being tested and refined. You should consider it to be a BETA VERSION.

Configuration

Three macros need to be defined (or not, if you want to disable the features) globally, e.g., in your CMake file:

  1. IYFT_ENABLE_PROFILING

Defining this macro will enable profiling. Even if you don't record anything, having profiling enabled will introduce a little bit of overhead to your code.

If this macro isn't defined, most IYFT_PROFILER macros will do nothing or return constant values.

  1. IYFT_THREAD_POOL_PROFILE

Defining this macro enables profiling of the thread pool. If this macro is defined, but IYFT_ENABLE_PROFILING isn't, profiling will still be disabled. Moreover, defining this macro will force ThreadPool.hpp to include ThreadProfiler.hpp.

  1. IYFT_PROFILER_WITH_IMGUI

Defining this macro allows you to draw the results retrieved from the profiler using Ocornut's Dear ImGui. Defining this macro will make the ThreadProfilerCore.hpp include imgui.h

Other options only apply to the thread profiler. They are documented in the ThreadProfilerSettings.hpp header and should be adjusted there. You should also use the said header to define custom scope tags, names and colours, suitable for your application.

Documentation

To build the full documentation, use Doxygen with the provided Doxyfile.

Usage

This is a simple example. For a more complete example that uses more features, check out the contents of the examples folder.

// This needs to be built with -DIYFT_ENABLE_PROFILING (and, optionally, -DIYFT_THREAD_POOL_PROFILE), e.g, on Linux:
//
// clang++ -pthread -std=c++11 -Wall -Wextra -pedantic -DIYFT_ENABLE_PROFILING -DIYFT_THREAD_POOL_PROFILE MinimalTest.cpp
// OR
// g++ -pthread -std=c++11 -Wall -Wextra -pedantic -DIYFT_ENABLE_PROFILING -DIYFT_THREAD_POOL_PROFILE MinimalTest.cpp
//
// C++11 is the minimum supported standard version.

#include <iostream>
#include <string>

// Add the profiler and designate this cpp file as the implementation
#define IYFT_THREAD_PROFILER_IMPLEMENTATION
// This is a lightweight header that should be included in the file that will contain
// the implementation and all files that contain functions you want to profile.
#include "ThreadProfiler.hpp"
// This header should only be included in two cases:
// 1. the cpp has IYFT_THREAD_PROFILER_IMPLEMENTATION defined and contains the
// implementation;
// 2. in any files where you need to access, save or process the records.
#include "ThreadProfilerCore.hpp"

// Add the pool AFTER the profiler if IYFT_THREAD_POOL_PROFILE is defined
#include "ThreadPool.hpp"

#define FRAME_COUNT 5

std::string withResult(std::size_t num, const std::string& str) {
    IYFT_PROFILE(TaskWithResult, iyft::ProfilerTag::NoTag);
    
    return str + std::to_string(num);
}

int main() {
    // Name this thread (optional - a name will be assigned by default otherwise)
    IYFT_PROFILER_NAME_THREAD("Main");
    
    // Start the recording
    IYFT_PROFILER_SET_RECORDING(true);
    
    // Create a thread pool with std::thread::hardware_concurrency() - 1 workers.
    iyft::ThreadPool pool;
    
    // This string needs to be kept alive until we're done with it.
    const std::string test = "test";
    
    for (std::size_t i = 0; i < FRAME_COUNT; ++i) {
        // Add a task from a function and obtain a future.
        auto result = pool.addTaskWithResult(withResult, i, test);
        
        // Add a task lambda with no result
        pool.addTask([](){
            IYFT_PROFILE(TaskWithoutAResult, iyft::ProfilerTag::NoTag);
            std::this_thread::sleep_for(std::chrono::milliseconds(5));
        });
        
        // Busy wait until all jobs are done
        pool.waitForAll();
        
        // This should happen immediately because we waited for all tasks
        IYFT_ASSERT(result.get() == (test + std::to_string(i)));
        
        // Mark the end of the frame and start a new one
        IYFT_PROFILER_NEXT_FRAME
    }
    
    // Write the results to an std::string and std::cout
    // Calling iyft::GetThreadProfiler().getResults() will automatically stop the
    // recording.
    std::cout << iyft::GetThreadProfiler().getResults().writeToString() << "\n";
    
    return 0;
}

Drawing in ImGui

If your engine or framework uses Ocornut's Dear ImGui, you may draw the recorded data directly.

// Make sure IYFT_PROFILER_WITH_IMGUI was defined or you'll get a ton of errors

#include "imgui.h"
#include "ThreadProfilerCore.hpp"

// ...

std::unique_ptr<iyft::ProfilerResults> profilerResults;
void drawiProfilerResults(float delta) {
    static float profilerZoom = 1.0f;
    
    ImGui::SetNextWindowSize(ImVec2(1200,750), ImGuiCond_FirstUseEver);
    if (ImGui::Begin("Profiler", nullptr)) {
        if (IYFT_PROFILER_STATUS == iyft::ProfilerStatus::EnabledAndNotRecording) {
            if (ImGui::Button("Start Recording")) {
                IYFT_PROFILER_SET_RECORDING(true);
            }
        } else if (IYFT_PROFILER_STATUS == iyft::ProfilerStatus::EnabledAndRecording) {
            if (ImGui::Button("Stop Recording")) {
                IYFT_PROFILER_SET_RECORDING(false);
                profilerResults = std::make_unique<iyft::ProfilerResults>(std::move(iyft::GetThreadProfiler().getResults()));
            }
        } else {
            // The profiler must be enabled for recording to work
            assert(0);
        }
        
        ImGui::SameLine();
        ImGui::SliderFloat("Zoom", &profilerZoom, iyft::ProfilerResults::GetMinScale(), iyft::ProfilerResults::GetMaxScale());
        
        if (profilerResults != nullptr) {
            profilerResults->drawInImGui(profilerZoom);
        } else {
            ImGui::Text("Results not yet loaded or recorded.");
        }
    }
    
    ImGui::End();
}

// ...

You'll get something like this: screenshot

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].