mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-26 16:11:02 +08:00
#0 [Misc] Update README.md
This commit is contained in:
parent
b10965ee92
commit
0c8246e61e
188
README.md
188
README.md
@ -1,4 +1,4 @@
|
|||||||
# easy_profiler [![2.0.0](https://img.shields.io/badge/version-2.0.0-009688.svg)](https://github.com/yse/easy_profiler/releases)
|
# easy_profiler [![2.0.1](https://img.shields.io/badge/version-2.0.1-009688.svg)](https://github.com/yse/easy_profiler/releases)
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/yse/easy_profiler.svg?branch=develop)](https://travis-ci.org/yse/easy_profiler)
|
[![Build Status](https://travis-ci.org/yse/easy_profiler.svg?branch=develop)](https://travis-ci.org/yse/easy_profiler)
|
||||||
[![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)
|
[![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)
|
||||||
@ -9,19 +9,21 @@
|
|||||||
1. [About](#about)
|
1. [About](#about)
|
||||||
2. [Key features](#key-features)
|
2. [Key features](#key-features)
|
||||||
3. [Usage](#usage)
|
3. [Usage](#usage)
|
||||||
- [Prepare build system](#prepare-build-system)
|
- [Integration](#integration)
|
||||||
- [General build system](#general)
|
- [General build system](#general)
|
||||||
- [CMake](#build-with-cmake)
|
- [CMake](#if-using-cmake)
|
||||||
- [Add profiling blocks](#add-profiling-blocks)
|
- [Inserting blocks](#inserting-blocks)
|
||||||
- [Collect blocks](#collect-blocks)
|
- [Storing variables](#storing-variables)
|
||||||
- [Collect via network](#collect-via-network)
|
- [Collect profiling data](#collect-profiling-data)
|
||||||
- [Collect via file](#collect-via-file)
|
- [Streaming over network](#streaming-over-network)
|
||||||
- [Note about context-switch](#note-about-context-switch)
|
- [Dump to file](#dump-to-file)
|
||||||
|
- [Note about thread context-switch events](#note-about-thread-context-switch-events)
|
||||||
|
- [Profiling application startup](#profiling-application-startup)
|
||||||
4. [Build](#build)
|
4. [Build](#build)
|
||||||
- [Linux](#linux)
|
- [Linux](#linux)
|
||||||
- [MacOS](#macos)
|
- [MacOS](#macos)
|
||||||
- [Windows](#windows)
|
- [Windows](#windows)
|
||||||
5. [Note about major release (v1 -> v2)](#status)
|
5. [Notes about major release (1.0 -> 2.0)](#status)
|
||||||
6. [License](#license)
|
6. [License](#license)
|
||||||
|
|
||||||
# About
|
# About
|
||||||
@ -53,71 +55,59 @@ _New UI style in version 2.0_
|
|||||||
- Extremely low overhead
|
- Extremely low overhead
|
||||||
- Low additional memory usage
|
- Low additional memory usage
|
||||||
- Cross-platform
|
- Cross-platform
|
||||||
- Measuring over network
|
- Profiling over network
|
||||||
- Capture thread context-switch events
|
- Capture thread context-switch events
|
||||||
- Fully remove integration via defines
|
- Store user variables (both single values and arrays)
|
||||||
- GUI could be connected to an application which is already profiling (so you can profile initialization of your application)
|
- 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
|
- 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
|
||||||
- Configurable timer type with CMakeLists or defines
|
- Configurable timer type with CMakeLists or preprocessor macros
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
## Prepare build system
|
## Integration
|
||||||
|
|
||||||
### General
|
### General
|
||||||
|
|
||||||
First of all you can specify path to include directory which contains `include/profiler` directory and define macro `BUILD_WITH_EASY_PROFILER`.
|
First of all you can specify path to include directory which contains `include/profiler` directory and define macro `BUILD_WITH_EASY_PROFILER`.
|
||||||
For linking with easy_profiler you can specify path to library.
|
For linking with easy_profiler you can specify path to library.
|
||||||
|
|
||||||
### Build with cmake
|
### If using 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:
|
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:
|
||||||
``` cmake
|
``` cmake
|
||||||
project(app_for_profiling)
|
project(my_application)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
main.cpp
|
main.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
#CMAKE_PREFIX_PATH should be set to <easy_profiler-release_dir>/lib/cmake/easy_profiler
|
# CMAKE_PREFIX_PATH should be set to <easy_profiler-release_dir>/lib/cmake/easy_profiler
|
||||||
find_package(easy_profiler REQUIRED)
|
find_package(easy_profiler REQUIRED) # STEP 1 #########################
|
||||||
|
|
||||||
add_executable(app_for_profiling ${SOURCES})
|
add_executable(my_application ${SOURCES})
|
||||||
|
|
||||||
target_link_libraries(app_for_profiling easy_profiler)
|
target_link_libraries(my_application easy_profiler) # STEP 2 ##########
|
||||||
```
|
```
|
||||||
|
|
||||||
## Add profiling blocks
|
## Inserting blocks
|
||||||
|
|
||||||
Example of usage.
|
Example of usage.
|
||||||
|
|
||||||
This code snippet will generate block with function name and Magenta color:
|
|
||||||
```cpp
|
|
||||||
#include <easy/profiler.h>
|
|
||||||
|
|
||||||
void frame() {
|
|
||||||
EASY_FUNCTION(profiler::colors::Magenta); // Magenta block with name "frame"
|
|
||||||
prepareRender();
|
|
||||||
calculatePhysics();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
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
|
|
||||||
(in this case it will have default color which is `Amber100`):
|
|
||||||
```cpp
|
```cpp
|
||||||
#include <easy/profiler.h>
|
#include <easy/profiler.h>
|
||||||
|
|
||||||
void foo() {
|
void foo() {
|
||||||
// some code
|
EASY_FUNCTION(profiler::colors::Magenta); // Magenta block with name "foo"
|
||||||
EASY_BLOCK("Calculating sum"); // Block with default color
|
|
||||||
|
EASY_BLOCK("Calculating sum"); // Begin block with default color == Amber100
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
EASY_BLOCK("Addition", profiler::colors::Red); // Scoped red block (no EASY_END_BLOCK needed)
|
EASY_BLOCK("Addition", profiler::colors::Red); // Scoped red block (no EASY_END_BLOCK needed)
|
||||||
sum += i;
|
sum += i;
|
||||||
}
|
}
|
||||||
EASY_END_BLOCK; // This ends "Calculating sum" block
|
EASY_END_BLOCK; // End of "Calculating sum" block
|
||||||
|
|
||||||
EASY_BLOCK("Calculating multiplication", profiler::colors::Blue500); // Blue block
|
EASY_BLOCK("Calculating multiplication", profiler::colors::Blue500); // Blue block
|
||||||
int mul = 1;
|
int mul = 1;
|
||||||
@ -125,57 +115,118 @@ void foo() {
|
|||||||
mul *= i;
|
mul *= i;
|
||||||
//EASY_END_BLOCK; // This is not needed because all blocks are ended on destructor when closing braces met
|
//EASY_END_BLOCK; // This is not needed because all blocks are ended on destructor when closing braces met
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
You can also use your own colors. easy_profiler is using standard 32-bit ARGB color format.
|
|
||||||
Example:
|
|
||||||
```cpp
|
|
||||||
#include <easy/profiler.h>
|
|
||||||
|
|
||||||
void bar() {
|
void bar() {
|
||||||
EASY_FUNCTION(0xfff080aa); // Function block with custom color
|
EASY_FUNCTION(0xfff080aa); // Function block with custom ARGB color
|
||||||
// some code
|
}
|
||||||
|
|
||||||
|
void baz() {
|
||||||
|
EASY_FUNCTION(); // Function block with default color == Amber100
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
## Collect blocks
|
|
||||||
|
|
||||||
There are two ways to capture blocks
|
EasyProfiler is using Google Material-Design colors palette, but you can use custom colors in ARGB format (like shown in example above).
|
||||||
|
The default color is `Amber100` (it is used when you do not specify color explicitly).
|
||||||
|
|
||||||
### Collect via network
|
## Storing variables
|
||||||
|
|
||||||
It's most prefered and convenient approach in many case.
|
Example of storing variables:
|
||||||
|
```cpp
|
||||||
|
#include <easy/profiler.h>
|
||||||
|
#include <easy/arbitrary_value.h> // EASY_VALUE, EASY_ARRAY are defined here
|
||||||
|
|
||||||
1. Initialize listening by `profiler::startListen()`. It's start new thread to listen on `28077` port the start-capture-signal from gui-application.
|
class Object {
|
||||||
2. To stop listening you can call `profiler::stopListen()` function.
|
Vector3 m_position; // Let's suppose Vector3 is a struct { float x, y, z; };
|
||||||
|
unsigned int m_id;
|
||||||
|
public:
|
||||||
|
void act() {
|
||||||
|
EASY_FUNCTION(profiler::colors::Cyan);
|
||||||
|
|
||||||
### Collect via file
|
// Dump variables values
|
||||||
|
constexpr auto Size = sizeof(Vector3) / sizeof(float);
|
||||||
|
EASY_VALUE("id", m_id);
|
||||||
|
EASY_ARRAY("position", &m_position.x, Size, profiler::color::Red);
|
||||||
|
|
||||||
1. Enable profiler by `EASY_PROFILER_ENABLE` macro
|
// Do something ...
|
||||||
2. Dump blocks to file in any place you want by `profiler::dumpBlocksToFile("test_profile.prof")` function
|
}
|
||||||
|
|
||||||
|
void loop(uint32_t N) {
|
||||||
|
EASY_FUNCTION();
|
||||||
|
EASY_VALUE("N", N, EASY_VIN("N")); /* EASY_VIN is used here to ensure
|
||||||
|
that this value id will always be
|
||||||
|
the same, because the address of N
|
||||||
|
can change */
|
||||||
|
for (uint32_t i = 0; i < N; ++i) {
|
||||||
|
// Do something
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Collect profiling data
|
||||||
|
|
||||||
|
There are two ways to collect profiling data: streaming over network and dumping data to file.
|
||||||
|
|
||||||
|
### Streaming over network
|
||||||
|
|
||||||
|
This is the most preferred and convenient method in many cases.
|
||||||
|
|
||||||
|
1. (In profiled app) Invoke `profiler::startListen()`. This will start new thread to listen `28077` port for the start-capture-signal from profiler_gui.
|
||||||
|
2. (In UI) Connect profiler_gui to your application using `hostname` or `IP-address`.
|
||||||
|
3. (In UI) Press `Start capture` button in profiler_gui.
|
||||||
|
4. (In UI) Press `Stop capture` button in profiler_gui to stop capturing and wait until profiled data will be passed over network.
|
||||||
|
5. (Optional step)(In profiled app) Invoke `profiler::stopListen()` to stop listening.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```cpp
|
```cpp
|
||||||
int main()
|
void main() {
|
||||||
{
|
profiler::startListen();
|
||||||
|
/* do work */
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dump to file
|
||||||
|
|
||||||
|
1. (Profiled application) Start capturing by putting `EASY_PROFILER_ENABLE` macro somewhere into the code.
|
||||||
|
2. (Profiled application) Dump profiled data to file in any place you want by `profiler::dumpBlocksToFile("test_profile.prof")` function.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```cpp
|
||||||
|
void main() {
|
||||||
EASY_PROFILER_ENABLE;
|
EASY_PROFILER_ENABLE;
|
||||||
/* do work*/
|
/* do work */
|
||||||
profiler::dumpBlocksToFile("test_profile.prof");
|
profiler::dumpBlocksToFile("test_profile.prof");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Note about context-switch
|
### Note about thread context-switch events
|
||||||
|
|
||||||
To capture a thread context-switch event you need:
|
To capture a thread context-switch events you need:
|
||||||
|
|
||||||
- On Windows: run profiling application "as administrator"
|
- On Windows: launch your application "as Administrator"
|
||||||
- On linux: you can run special `systemtap` script with root privileges as follow (example on Fedora):
|
- On Linux: you can launch special `systemtap` script with root privileges as follow (example on Fedora):
|
||||||
```bash
|
```bash
|
||||||
#stap -o /tmp/cs_profiling_info.log scripts/context_switch_logger.stp name APPLICATION_NAME
|
#stap -o /tmp/cs_profiling_info.log scripts/context_switch_logger.stp name APPLICATION_NAME
|
||||||
```
|
```
|
||||||
APPLICATION_NAME - name of profiling application
|
APPLICATION_NAME - name of your application
|
||||||
|
|
||||||
There are some known issues on a linux based systems (for more information see [wiki](https://github.com/yse/easy_profiler/wiki/Known-bugs-and-issues))
|
There are some known issues on a linux based systems (for more information see [wiki](https://github.com/yse/easy_profiler/wiki/Known-bugs-and-issues))
|
||||||
|
|
||||||
|
### Profiling application startup
|
||||||
|
|
||||||
|
To profile your application startup (when using [network](#streaming-over-network) method) add `EASY_PROFILER_ENABLE` macro into the code together with `profiler::startListen()`.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```cpp
|
||||||
|
void main() {
|
||||||
|
EASY_PROFILER_ENABLE;
|
||||||
|
profiler::startListen();
|
||||||
|
/* do work */
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This will allow you to collect profiling data before profiler_gui connection. profiler_gui will automatically display capturing dialog window after successful connection to the profiled application.
|
||||||
|
|
||||||
# Build
|
# Build
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
@ -231,13 +282,10 @@ $ cmake .. -G "Visual Studio 12 2013 Win64"
|
|||||||
```
|
```
|
||||||
|
|
||||||
# Status
|
# Status
|
||||||
Branch `develop` contains all v2.0.0 features and new UI style.
|
Branch `develop` contains all v2.0.0 features and new UI style.
|
||||||
|
Please, note that .prof file header has changed in v2.0.0:
|
||||||
Please, note that .prof file header has changed in v2.0.0.
|
|
||||||
Now it is:
|
|
||||||
```cpp
|
```cpp
|
||||||
struct EasyFileHeader
|
struct EasyFileHeader {
|
||||||
{
|
|
||||||
uint32_t signature = 0;
|
uint32_t signature = 0;
|
||||||
uint32_t version = 0;
|
uint32_t version = 0;
|
||||||
profiler::processid_t pid = 0;
|
profiler::processid_t pid = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user