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