1# easy_profiler [![1.3.0](https://img.shields.io/badge/version-1.3.0-009688.svg)](https://github.com/yse/easy_profiler/releases) 2 3[![Build Status](https://travis-ci.org/yse/easy_profiler.svg?branch=develop)](https://travis-ci.org/yse/easy_profiler) 4[![Build Status](https://ci.appveyor.com/api/projects/status/github/yse/easy_profiler?branch=develop&svg=true)](https://ci.appveyor.com/project/yse/easy-profiler/branch/develop) 5 6[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) 7[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) 8 9 101. [About](#about) 112. [Key features](#key-features) 123. [Usage](#usage) 13 - [Prepare build system](#prepare-build-system) 14 - [General build system](#general) 15 - [CMake](#build-with-cmake) 16 - [Add profiling blocks](#add-profiling-blocks) 17 - [Collect blocks](#collect-blocks) 18 - [Collect via network](#collect-via-network) 19 - [Collect via file](#collect-via-file) 20 - [Note about context-switch](#note-about-context-switch) 214. [Build](#build) 22 - [Linux](#linux) 23 - [Windows](#windows) 245. [License](#license) 25 26# About 27Lightweight cross-platform profiler library for c++ 28 29You can profile any function in you code. Furthermore this library provide measuring time of any block of code. 30For example, information for 12 millions of blocks is using less than 300Mb of memory. 31Working profiler slows your application execution for only 1-2%. 32 33![Block time](https://hsto.org/files/3e4/afe/8b7/3e4afe8b77ac4ad3a6f8c805be4b7f13.png) 34_Average overhead per block is about 15ns/block (tested on Intel Core i7-5930K 3.5GHz, Win7)_ 35 36Disabled profiler will not affect your application execution in any way. You can leave it in your Release build 37and enable it at run-time at any moment during application launch to see what is happening at the moment. 38 39Also the library can capture system's context switch events between threads. Context switch information includes 40duration, target thread id, thread owner process id, thread owner process name. 41 42You can see the results of measuring in simple GUI application which provides full statistics and renders beautiful time-line. 43 44![GUI screenshot](https://cloud.githubusercontent.com/assets/1775230/24852044/a0b1edd0-1dde-11e7-8736-7052b840ad06.png) 45_Profiling CryEngine SDK example_ 46 47# Key features 48 49- Extremely low overhead 50- Low additional memory usage 51- Cross-platform 52- Measuring over network 53- Capture thread context-switch events 54- Fully remove integration via defines 55- GUI could be connected to an application which is already profiling (so you can profile initialization of your application) 56- Monitor main thread fps at real-time in GUI even if profiling is disabled or draw your own HUD/fps-plot directly in your application using data provided by profiler 57- Configurable timer type with CMakeLists or defines 58 59# Usage 60 61## Prepare build system 62 63### General 64 65First of all you can specify path to include directory which contains `include/profiler` directory and define macro `BUILD_WITH_EASY_PROFILER`. 66For linking with easy_profiler you can specify path to library. 67 68### Build with cmake 69 70If you are using `cmake` set `CMAKE_PREFIX_PATH` to `lib/cmake/easy_profiler` directory (from [release](https://github.com/yse/easy_profiler/releases) package) and use function `find_package(easy_profiler)` with `target_link_libraries(... easy_profiler)`. Example: 71 72``` cmake 73project(app_for_profiling) 74 75set(SOURCES 76 main.cpp 77) 78 79#CMAKE_PREFIX_PATH should be set to <easy_profiler-release_dir>/lib/cmake/easy_profiler 80find_package(easy_profiler REQUIRED) 81 82add_executable(app_for_profiling ${SOURCES}) 83 84target_link_libraries(app_for_profiling easy_profiler) 85``` 86 87## Add profiling blocks 88 89Example of usage. 90 91This code snippet will generate block with function name and Magenta color: 92```cpp 93#include <easy/profiler.h> 94 95void frame() { 96 EASY_FUNCTION(profiler::colors::Magenta); // Magenta block with name "frame" 97 prepareRender(); 98 calculatePhysics(); 99} 100``` 101 102To profile any block you may do this as following. 103You can specify these blocks also with Google material design colors or just set name of the block 104(in this case it will have default color which is `Amber100`): 105```cpp 106#include <easy/profiler.h> 107 108void foo() { 109 // some code 110 EASY_BLOCK("Calculating sum"); // Block with default color 111 int sum = 0; 112 for (int i = 0; i < 10; ++i) { 113 EASY_BLOCK("Addition", profiler::colors::Red); // Scoped red block (no EASY_END_BLOCK needed) 114 sum += i; 115 } 116 EASY_END_BLOCK; // This ends "Calculating sum" block 117 118 EASY_BLOCK("Calculating multiplication", profiler::colors::Blue500); // Blue block 119 int mul = 1; 120 for (int i = 1; i < 11; ++i) 121 mul *= i; 122 //EASY_END_BLOCK; // This is not needed because all blocks are ended on destructor when closing braces met 123} 124``` 125 126You can also use your own colors. easy_profiler is using standard 32-bit ARGB color format. 127Example: 128```cpp 129#include <easy/profiler.h> 130 131void bar() { 132 EASY_FUNCTION(0xfff080aa); // Function block with custom color 133 // some code 134} 135``` 136## Collect blocks 137 138There are two ways to cature blocks 139 140### Collect via network 141 142It's most prefered and convenient approach in many case. 143 1441. Initialize listening by `profiler::startListen()`. It's start new thread to listen on `28077` port the start-capture-signal from gui-application. 1452. To stop listening you can call `profiler::stopListen()` function. 146 147### Collect via file 148 1491. Enable profiler by `EASY_PROFILER_ENABLE` macro 1502. Dump blocks to file in any place you want by `profiler::dumpBlocksToFile("test_profile.prof")` function 151 152Example: 153```cpp 154int main() 155{ 156 EASY_PROFILER_ENABLE; 157 /* do work*/ 158 profiler::dumpBlocksToFile("test_profile.prof"); 159} 160``` 161 162### Note about context-switch 163 164To capture a thread context-switch event you need: 165 166- On Windows: run profiling application "as administrator" 167- On linux: you can run special `systemtap` script with root privileges as follow (example on Fedora): 168```bash 169#stap -o /tmp/cs_profiling_info.log scripts/context_switch_logger.stp name APPLICATION_NAME 170``` 171APPLICATION_NAME - name of profiling application 172 173# Build 174 175## Prerequisites 176 177* CMake 3.0 or higher 178* Compiler with c++11 support 179 * for Unix systems: compiler with `thread_local` support is **highly recommended**: _GCC >=4.8_, _Clang >=3.3_ 180 181Additional requirements for GUI: 182* Qt 5.3.0 or higher 183 184## Linux 185 186```bash 187$ mkdir build 188$ cd build 189$ cmake -DCMAKE_BUILD_TYPE="Release" .. 190$ make 191``` 192 193## Windows 194 195If you are using QtCreator IDE you can just open `CMakeLists.txt` file in root directory. 196If you are using Visual Studio you can generate solution by cmake generator command. 197Examples shows how to generate Win64 solution for Visual Studio 2013. To generate for another version use proper cmake generator (-G "name of generator"). 198 199### Way 1 200Specify path to cmake scripts in Qt5 dir (usually in lib/cmake subdir) and execute cmake generator command, 201for example: 202```batch 203$ mkdir build 204$ cd build 205$ cmake -DCMAKE_PREFIX_PATH="C:\Qt\5.3\msvc2013_64\lib\cmake" .. -G "Visual Studio 12 2013 Win64" 206``` 207 208### Way 2 209Create system variable "Qt5Widgets_DIR" and set it's value to "[path-to-Qt5-binaries]\lib\cmake\Qt5Widgets". 210For example, "C:\Qt\5.3\msvc2013_64\lib\cmake\Qt5Widgets". 211And then run cmake generator as follows: 212```batch 213$ mkdir build 214$ cd build 215$ cmake .. -G "Visual Studio 12 2013 Win64" 216``` 217 218# License 219 220Licensed under either of 221- MIT license ([LICENSE.MIT](LICENSE.MIT) or http://opensource.org/licenses/MIT) 222- Apache License, Version 2.0, ([LICENSE.APACHE](LICENSE.APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 223 224at your option. 225