0
0
mirror of https://github.com/yse/easy_profiler.git synced 2024-12-28 01:04:41 +08:00
easy_profiler/README.md

225 lines
7.4 KiB
Markdown
Raw Normal View History

2017-05-08 12:32:56 +03:00
# easy_profiler [![1.2.0](https://img.shields.io/badge/version-1.2.0-009688.svg)](https://github.com/yse/easy_profiler/releases)
2016-11-13 17:34:19 +03:00
[![Build Status](https://travis-ci.org/yse/easy_profiler.svg?branch=develop)](https://travis-ci.org/yse/easy_profiler)
2017-08-30 00:41:27 +04:00
[![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)
2016-11-13 17:34:19 +03:00
2017-03-30 06:30:11 +03:00
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
2016-11-13 16:31:27 +03:00
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
2017-03-30 06:28:30 +03:00
2016-08-31 22:47:17 +03:00
1. [About](#about)
2017-03-01 11:40:47 +03:00
2. [Key features](#key-features)
3. [Usage](#usage)
2017-02-07 06:22:34 +03:00
- [Prepare build system](#prepare-build-system)
- [General build system](#general)
- [CMake](#build-with-cmake)
2017-01-21 01:28:53 +04:00
- [Add profiling blocks](#add-profiling-blocks)
- [Collect blocks](#collect-blocks)
2017-03-01 12:02:47 +03:00
- [Collect via network](#collect-via-network)
- [Collect via file](#collect-via-file)
2017-03-01 13:20:51 +03:00
- [Note about context-switch](#note-about-context-switch)
2017-03-01 11:40:47 +03:00
4. [Build](#build)
2016-08-31 22:47:17 +03:00
- [Linux](#linux)
- [Windows](#windows)
2017-03-30 06:19:45 +03:00
5. [License](#license)
2016-08-31 22:47:17 +03:00
# About
2016-09-26 22:00:22 +03:00
Lightweight cross-platform profiler library for c++
2016-06-29 06:47:50 +04:00
2016-09-15 00:08:53 +03:00
You can profile any function in you code. Furthermore this library provide measuring time of any block of code.
2016-09-15 00:33:47 +03:00
For example, information for 12 millions of blocks is using less than 300Mb of memory.
Working profiler slows your application execution for only 1-2%.
2016-12-25 13:03:47 +03:00
![Block time](https://hsto.org/files/3e4/afe/8b7/3e4afe8b77ac4ad3a6f8c805be4b7f13.png)
2016-12-27 21:01:12 +03:00
_Average overhead per block is about 15ns/block (tested on Intel Core i7-5930K 3.5GHz, Win7)_
2016-12-25 13:03:47 +03:00
2016-09-15 00:33:47 +03:00
Disabled profiler will not affect your application execution in any way. You can leave it in your Release build
2016-11-13 15:54:06 +03:00
and enable it at run-time at any moment during application launch to see what is happening at the moment.
2016-09-15 00:33:47 +03:00
Also the library can capture system's context switch events between threads. Context switch information includes
duration, target thread id, thread owner process id, thread owner process name.
2016-09-15 00:08:53 +03:00
You can see the results of measuring in simple GUI application which provides full statistics and renders beautiful time-line.
2016-06-29 06:47:50 +04:00
2017-04-10 11:14:09 +03:00
![GUI screenshot](https://cloud.githubusercontent.com/assets/1775230/24852044/a0b1edd0-1dde-11e7-8736-7052b840ad06.png)
2017-05-07 13:40:23 +03:00
_Profiling CryEngine SDK example_
2016-11-05 19:24:12 +03:00
2017-03-01 11:40:47 +03:00
# Key features
- Extremely low overhead
- Low additional memory usage
- Cross-platform
- Measuring over network
- Capture thread context-switch events
- Fully remove integration via defines
2017-04-07 23:51:34 +03:00
- GUI could be connected to an application which is already profiling (so you can profile initialization of your application)
- 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
2017-05-07 13:40:23 +03:00
- Configurable timer type with CMakeLists or defines
2017-03-01 11:40:47 +03:00
2016-08-31 22:47:17 +03:00
# Usage
2017-02-07 06:22:34 +03:00
## Prepare build system
### General
2017-01-21 01:25:06 +04:00
2016-09-30 00:12:36 +04:00
First of all you can specify path to include directory which contains `include/profiler` directory and define macro `BUILD_WITH_EASY_PROFILER`.
2016-09-15 00:08:53 +03:00
For linking with easy_profiler you can specify path to library.
2016-08-31 22:47:17 +03:00
2017-02-07 06:22:34 +03:00
### Build with cmake
If 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:
2017-02-07 06:22:34 +03:00
``` cmake
project(app_for_profiling)
set(SOURCES
main.cpp
)
#CMAKE_PREFIX_PATH should be set to <easy_profiler-release_dir>/lib/cmake/easy_profiler
2017-02-07 06:22:34 +03:00
find_package(easy_profiler REQUIRED)
add_executable(app_for_profiling ${SOURCES})
target_link_libraries(app_for_profiling easy_profiler)
```
## Add profiling blocks
2016-06-29 06:47:50 +04:00
Example of usage.
2016-09-15 00:08:53 +03:00
This code snippet will generate block with function name and Magenta color:
2016-06-29 06:47:50 +04:00
```cpp
2016-10-21 22:21:25 +03:00
#include <easy/profiler.h>
2016-08-31 22:47:17 +03:00
2016-09-15 00:08:53 +03:00
void frame() {
2016-09-15 00:33:47 +03:00
EASY_FUNCTION(profiler::colors::Magenta); // Magenta block with name "frame"
2016-09-07 22:12:25 +03:00
prepareRender();
calculatePhysics();
2016-06-29 06:47:50 +04:00
}
```
2016-09-15 00:08:53 +03:00
To profile any block you may do this as following.
You can specify these blocks also with Google material design colors or just set name of the block
2016-09-15 00:33:47 +03:00
(in this case it will have default color which is `Amber100`):
2016-06-29 06:47:50 +04:00
```cpp
2016-10-21 22:21:25 +03:00
#include <easy/profiler.h>
2016-08-31 22:47:17 +03:00
2016-11-06 03:56:30 +03:00
void foo() {
2016-09-15 00:08:53 +03:00
// some code
2016-09-15 00:33:47 +03:00
EASY_BLOCK("Calculating sum"); // Block with default color
2016-09-15 00:08:53 +03:00
int sum = 0;
2016-11-06 03:56:30 +03:00
for (int i = 0; i < 10; ++i) {
EASY_BLOCK("Addition", profiler::colors::Red); // Scoped red block (no EASY_END_BLOCK needed)
2016-09-07 22:12:25 +03:00
sum += i;
2016-11-06 03:56:30 +03:00
}
EASY_END_BLOCK; // This ends "Calculating sum" block
2016-09-07 22:12:25 +03:00
2016-09-15 00:33:47 +03:00
EASY_BLOCK("Calculating multiplication", profiler::colors::Blue500); // Blue block
2016-09-15 00:08:53 +03:00
int mul = 1;
for (int i = 1; i < 11; ++i)
2016-09-07 22:12:25 +03:00
mul *= i;
2016-11-06 03:56:30 +03:00
//EASY_END_BLOCK; // This is not needed because all blocks are ended on destructor when closing braces met
2016-06-29 06:47:50 +04:00
}
```
2016-09-15 00:08:53 +03:00
2016-09-15 00:33:47 +03:00
You can also use your own colors. easy_profiler is using standard 32-bit ARGB color format.
2016-09-15 00:08:53 +03:00
Example:
```cpp
2016-10-21 22:21:25 +03:00
#include <easy/profiler.h>
2016-09-15 00:08:53 +03:00
2016-11-06 03:56:30 +03:00
void bar() {
2016-09-15 00:33:47 +03:00
EASY_FUNCTION(0xfff080aa); // Function block with custom color
2016-09-15 00:08:53 +03:00
// some code
}
```
2017-01-21 01:25:06 +04:00
## Collect blocks
2017-03-01 12:02:22 +03:00
There are two ways to cature blocks
### Collect via network
It's most prefered and convenient approach in many case.
1. Initialize listening by `profiler::startListen()`. It's start new thread to listen on `28077` port the start-capture-signal from gui-application.
2. To stop listening you can call `profiler::stopListen()` function.
### Collect via file
1. Enable profiler by `EASY_PROFILER_ENABLE` macro
2. Dump blocks to file in any place you want by `profiler::dumpBlocksToFile("test_profile.prof")` function
Example:
```cpp
int main()
{
EASY_PROFILER_ENABLE;
/* do work*/
profiler::dumpBlocksToFile("test_profile.prof");
}
```
2016-09-15 00:08:53 +03:00
2017-03-01 13:20:51 +03:00
### Note about context-switch
To capture a thread context-switch event you need:
- On Windows: run profiling application "as administrator"
- On linux: you can run special `systemtap` script with root privileges as follow (example on Fedora):
```bash
#stap -o /tmp/cs_profiling_info.log scripts/context_switch_logger.stp name APPLICATION_NAME
```
APPLICATION_NAME - name of profiling application
2016-09-26 22:00:22 +03:00
# Build
## Prerequisites
For core:
* compiler with c++11 support
2016-11-13 15:54:06 +03:00
* cmake 3.0 or higher
2016-09-26 22:00:22 +03:00
For GUI:
2016-11-13 15:54:06 +03:00
* Qt 5.3.0 or higher
2016-09-26 22:00:22 +03:00
## Linux
```bash
$ mkdir build
$ cd build
$ cmake ..
$ make
```
## Windows
If you are using QtCreator IDE you can just open `CMakeLists.txt` file in root directory.
If you are using Visual Studio you can generate solution by cmake generator command.
2016-11-13 15:54:06 +03:00
Examples shows how to generate Win64 solution for Visual Studio 2013. To generate for another version use proper cmake generator (-G "name of generator").
2016-09-26 22:00:22 +03:00
### Way 1
Specify path to cmake scripts in Qt5 dir (usually in lib/cmake subdir) and execute cmake generator command,
for example:
```batch
$ mkdir build
$ cd build
$ cmake -DCMAKE_PREFIX_PATH="C:\Qt\5.3\msvc2013_64\lib\cmake" .. -G "Visual Studio 12 2013 Win64"
```
### Way 2
Create system variable "Qt5Widgets_DIR" and set it's value to "[path-to-Qt5-binaries]\lib\cmake\Qt5Widgets".
For example, "C:\Qt\5.3\msvc2013_64\lib\cmake\Qt5Widgets".
And then run cmake generator as follows:
```batch
$ mkdir build
$ cd build
$ cmake .. -G "Visual Studio 12 2013 Win64"
```
2017-03-30 06:19:45 +03:00
2017-03-30 06:20:25 +03:00
# License
2017-03-30 06:19:45 +03:00
Licensed under either of
2017-03-30 06:25:07 +03:00
- MIT license ([LICENSE.MIT](LICENSE.MIT) or http://opensource.org/licenses/MIT)
- Apache License, Version 2.0, ([LICENSE.APACHE](LICENSE.APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
2017-03-30 06:19:45 +03:00
at your option.