Skip to content

Commit

Permalink
Update from upstream (#1)
Browse files Browse the repository at this point in the history
* yse#31 intermediate commit: added basic API for arbitrary values profiling. Still not working.

* yse#31 build fix

* yse#31 added arbitrary value id

* yse#75 Windows build

(cherry picked from commit ec720bf)

* #0 [Core] Added constexpr support macros and refactored extract_... functions

* yse#31 [Core] further work on arbitrary values

* #0 [Core] Rearranged include files

* #0 [Core] A lot of code refactoring

* #0 [Core][GUI] refactoring

* #0 [Core] refactoring

* #0 [Core] Windows build

* #0 Windows build

* #0 Build fix >:E

* yse#31 Single arbitrary values can be displayed in GUI as events + value converted to text

* #0 [GUI] Styling

* #0 [GUI] Styling

* #0 MSVC2013 build

* #0 [GUI] Warning fix: typo, forgotten return

* #0 [GUI] Styling

* yse#31 arbitrary value interface small refactoring

* #0 [GUI] Styling

* #0 [GUI] Styling

* #0 [GUI] Styling. Themes.

* #0 [GUI] Styling and optimization

* #0 [GUI] Windows styling and consterxpr fix for some Qt versions

* yse#81 [Core] Added an option to choose function names format

* yse#31 [GUI] Arbitrary values viewer progress

* #0 [GUI] Appearance progress

* yse#31 [GUI] Arbitrary values viewer progress

* #0 [GUI] Appearance

* #0 [GUI] HierarchyTree: Finally replaced colored rows with colored squares in front of block name. These squares can not be turned off from now.

* yse#31 [GUI] Arbitrary values viewer begin. Refactoring.

* yse#31 [Core] Fixed issue with storing arbitrary value while dumping. // [GUI] Further values viewer progress.

* Sample: build when SAMPLE_NETWORK_TEST is undefined

* minor refactoring

* yse#31 Basic arbitrary values viewer chart

* Windows build

* Older compiler build

* Older compiler build

* yse#75 [Core] No more waiting behavior when dumping blocks. Current solution resolves possible dead-lock but restricts any Events out of Frame bounds (You can see that the last event for LoadingResources thread in the profiler_sample is always absent).

* Install with include hierarhy

* yse#75 [Core] No waiting when dumping blocks. All events should now be stored properly.

* Release 2.0 further work. Intermediate commit.

* yse#31 [Gui] Big update for arbitrary values viewer. It is now viable and can be used to inspect user metrics. Currently arbitrary values viewer is built into blocks list widget.

* #0 [Gui] Saving dialog geometry; Added refresh button to arbitrary values widget; Fixed zoom-in algorithm

* yse#31 [Gui] Arbitrary values viewer bug fixes

* #0 [Gui] Large portion of refactoring; Replaced bunch of threads with thread pool; Small fixes for arbitrary values viewer

* #0 Updated copyright dates; [Gui] thread_pool.cpp MSVC build fix; [Core] Renamed getCurrentTime() to profiler::clock::now() + renamed profiler::currentTime() to profiler::now()

* #0 Simplified some lambdas

* yse#89 Trying to fix high-dpi displays problem

* yse#31 [Gui] Intermediate commit: implementing O(n) chart (kinda...) to be able to analyse algorithm complexity depending on certain arbitrary value

* yse#31 [Gui] Complexity charts for arbitrary value viewer

* yse#31 [Gui] Hide slider when displaying complexity chart

* yse#31 [Gui] Arbitrary values viewer: fixed performance problem, added icons for chart types

* yse#31 [Gui] Fixed mouse indicator for complexity chart; fixed buildTree(); added stub for future export values to .csv

* #0 [Gui] Fixed popup and double click on thread names on Diagram

* yse#31 [Gui] Fixed appox. line painting for complexity chart; Added export to .csv for regular chart type (timestamp;value);

* #0 [Gui] Paint background for current item for tree-widget

* Add math functions for calculation complexity

* yse#67 [Converter] Build fix after merging to release_2_0

* #0 [Gui] TreeView style fixes

* #0 [Gui] Thread pool fix: there was a possibility that not all tasks would be executed

* #0 [Gui] Added background jobs to thread pool and removed detached threads from code

* yse#31 [Gui] Implemented zoom for complexity chart mode; Implemented export to .csv for complexity mode

* #0 [Gui] Mac build fix

* #0 [Gui] Fixed typo

* #0 [Gui] Windows styling fix

* yse#31 [Core] Arbitrary values: replaced size_t with uint16_t; [Gui] Added support of arrays to arbitrary values tree

* #0 [Gui] Fixed hierarchy building for zero duration blocks - events and arbitrary values are always visible

* yse#31 [Gui] Double click on arbitrary value on the Diagram will open values viewer and will select appropriate arbitrary value

* yse#31 [UI] Open several arbitrary values viewer windows

* yse#31 [UI] Arbitrary values: fixed multi-window viewer

* yse#31 [UI] Highlight current selected block boundaries on arbitrary value chart

* yse#31 [UI] Fixed current block boundaries painting

* #0 [UI] Added viewport info widget. See [Settings] -> [See viewport info]

* yse#100 [UI] Implemented zoom-in button

* #0 [UI] Adjusted search boxes in Hierarchy widget and Blocks Descriptors Widget

* yse#31 [UI] Added arbitrary value tool-tip to Hierarchy tree widget (Try to move mouse cursor over Name column)

* yse#31 [UI] Added tooltip for arbitrary values to the Diagram

* yse#31 [UI] Amend. Forgotten files.

* #0 [UI] Diagram tool-tips fix: no tool-tips if mouse cursor is over another widget (opened settings for example)

* #0 [UI] Arbitrary value ToolTip styling fix; Viewport info fix;

* yse#48 [Core] Rearranged file header members order to minimize padding;
[Core] Changed version to 2.0.0;

* #0 Update README.md

* yse#67 [Converter] Rewrote json converter, arbitrary values would be added soon

* yse#91 [UI] Added snapshot tool stub; Working on saving blocks to file from UI

* yse#91 [UI] Snapshot feature further progress (intermediate commit)

* yse#91 [UI] Snapshot icon (actually called "crop")

* #0 [core] installing profiler_converter

* yse#91 [UI] .prof serializator (intermediate commit)

* yse#91 [Core][UI] functions profiler::writeTreesToFile(), profiler::writeTreesToStream() are now working. Snapshot feature is now working: select an area on Diagram (with right mouse button or double-click) and press Snapshot button to save it to separate file.

* #0 [Sample] Rollback - profiler_sample is standalone again (do not need to connect gui)

* #0 Update readme

* #0 Added new UI image to README.md

* Update README.md

* #0 [Core] refactoring

* #0 [UI] refactoring

* #0 [Core] Windows build

* #0 [Core] refactoring

* #0 [Core] findRange() fix for writeTreesToStream()

* #0 [Core] fixed typo

* yse#108 fix [Core] clang build for arbitrary values

* #0 [UI] Tooltip fix

* yse#89 [UI] High DPI displays fix + System scaling factor

* # [UI] Styles and refactoring

* #0 [UI] UI styles

* #0 [Misc] modified gitignore

* #0 [UI] Style

* #0 [UI] refactoring

* #0 [UI] Fixed zooming for charts (histogram, arbitrary value) with mouse wheel

* #0 [Misc] Update README.md

* #0 Updated image in README.md

* yse#106 [Core][UI] Added possibility to add user bookmarks with double-clicking on a timeline in the Diagram window.
yse#112 [UI] Fixed losing focus (and getting under MainWindow) for Blocks widget.
#0 [UI] UI styling, added custom window header and dialogs (could be turned off/on and adjusted position at [Settings -> Appearance] menu).

* yse#106 [UI] Rising a tooltip when passing cursor over a bookmark; #0 [UI] Minor fixes

* yse#106 [Core][UI] Fixed reading bookmarks with empty text; Fixed overriding and restoring mouse cursor shape when hovering bookmark at the Diagram widget;
#0 [UI] Waiting until saving file is finished when closing the UI.

* Update README.md

* Update README.md
  • Loading branch information
manimax3 authored Jun 29, 2018
1 parent 42fae6f commit f6d74c1
Show file tree
Hide file tree
Showing 181 changed files with 21,923 additions and 9,007 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ bin
*build*
.*
*.user
/*.prof
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ option(EASY_PROFILER_NO_GUI "Build easy_profiler without the GUI application (re
set(EASY_PROFILER_NO_CONVERTER ON)
set(EASY_PROFILER_NO_SAMPLES ON)

set(EASY_PROGRAM_VERSION_MAJOR 1)
set(EASY_PROGRAM_VERSION_MINOR 3)
set(EASY_PROGRAM_VERSION_MAJOR 2)
set(EASY_PROGRAM_VERSION_MINOR 1)
set(EASY_PROGRAM_VERSION_PATCH 0)
set(EASY_PRODUCT_VERSION_STRING "${EASY_PROGRAM_VERSION_MAJOR}.${EASY_PROGRAM_VERSION_MINOR}.${EASY_PROGRAM_VERSION_PATCH}")

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2017 Sergey Yagovtsev, Victor Zarubkin
Copyright (c) 2016-2018 Sergey Yagovtsev, Victor Zarubkin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.MIT
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2017 Sergey Yagovtsev, Victor Zarubkin
Copyright (c) 2016-2018 Sergey Yagovtsev, Victor Zarubkin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
202 changes: 139 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
# easy_profiler [![1.3.0](https://img.shields.io/badge/version-1.3.0-009688.svg)](https://github.com/yse/easy_profiler/releases)
# easy_profiler [![2.0.1](https://img.shields.io/badge/stable-2.0.1-009688.svg)](https://github.com/yse/easy_profiler/releases) [![2.1.0](https://img.shields.io/badge/latest-2.1.0-f57f17.svg)](https://github.com/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)

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)


1. [About](#about)
2. [Key features](#key-features)
3. [Usage](#usage)
- [Prepare build system](#prepare-build-system)
- [Integration](#integration)
- [General build system](#general)
- [CMake](#build-with-cmake)
- [Add profiling blocks](#add-profiling-blocks)
- [Collect blocks](#collect-blocks)
- [Collect via network](#collect-via-network)
- [Collect via file](#collect-via-file)
- [Note about context-switch](#note-about-context-switch)
- [CMake](#if-using-cmake)
- [Inserting blocks](#inserting-blocks)
- [Storing variables](#storing-variables)
- [Collect profiling data](#collect-profiling-data)
- [Streaming over network](#streaming-over-network)
- [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)
- [Linux](#linux)
- [MacOS](#macos)
- [Windows](#windows)
5. [License](#license)
5. [Notes about major release (1.0 -> 2.0)](#status)
6. [License](#license)

# About
Lightweight cross-platform profiler library for c++
Expand All @@ -45,134 +47,188 @@ You can see the results of measuring in simple GUI application which provides fu
![GUI screenshot](https://cloud.githubusercontent.com/assets/1775230/24852044/a0b1edd0-1dde-11e7-8736-7052b840ad06.png)
_Profiling CryEngine SDK example_

![New UI Style](https://user-images.githubusercontent.com/10530007/40890463-0ab378f8-677f-11e8-9b10-9c62ffb7d5b8.png)
_New UI style in version 2.0_

# Key features

- Extremely low overhead
- Low additional memory usage
- Cross-platform
- Measuring over network
- Profiling over network
- 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)
- 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
- 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
- Save a snapshot (selected area) of profiled data from file
- Add bookmarks at any place on the timeline
- Configurable timer type with CMakeLists or preprocessor macros

# Usage

## Prepare build system
## Integration

### General

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.

### 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
project(app_for_profiling)
project(my_application)
set(SOURCES
main.cpp
)
#CMAKE_PREFIX_PATH should be set to <easy_profiler-release_dir>/lib/cmake/easy_profiler
find_package(easy_profiler REQUIRED)
# CMAKE_PREFIX_PATH should be set to <easy_profiler-release_dir>/lib/cmake/easy_profiler
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.

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
#include <easy/profiler.h>

void foo() {
// some code
EASY_BLOCK("Calculating sum"); // Block with default color
EASY_FUNCTION(profiler::colors::Magenta); // Magenta block with name "foo"

EASY_BLOCK("Calculating sum"); // Begin block with default color == Amber100
int sum = 0;
for (int i = 0; i < 10; ++i) {
EASY_BLOCK("Addition", profiler::colors::Red); // Scoped red block (no EASY_END_BLOCK needed)
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
int mul = 1;
for (int i = 1; i < 11; ++i)
mul *= i;
//EASY_END_BLOCK; // This is not needed because all blocks are ended on destructor when closing braces met
}

void bar() {
EASY_FUNCTION(0xfff080aa); // Function block with custom ARGB color
}

void baz() {
EASY_FUNCTION(); // Function block with default color == Amber100
}
```

You can also use your own colors. easy_profiler is using standard 32-bit ARGB color format.
Example:
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).

## Storing variables

Example of storing variables:
```cpp
#include <easy/profiler.h>
#include <easy/arbitrary_value.h> // EASY_VALUE, EASY_ARRAY are defined here

void bar() {
EASY_FUNCTION(0xfff080aa); // Function block with custom color
// some code
}
class Object {
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);

// 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);

// Do something ...
}

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 blocks
There are two ways to capture blocks
## Collect profiling data
### Collect via network
There are two ways to collect profiling data: streaming over network and dumping data to file.
It's most prefered and convenient approach in many case.
### Streaming over network
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.
This is the most preferred and convenient method in many cases.
### Collect via file
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.
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
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
int main()
{
void main() {
EASY_PROFILER_ENABLE;
/* do work*/
/* do work */
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 linux: you can run special `systemtap` script with root privileges as follow (example on Fedora):
- On Windows: launch your application "as Administrator"
- On Linux: you can launch 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
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))

### 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

## Prerequisites
Expand Down Expand Up @@ -227,6 +283,26 @@ $ cd build
$ cmake .. -G "Visual Studio 12 2013 Win64"
```

# Status
Branch `develop` contains all v2.0.0 features and new UI style.
Please, note that .prof file header has changed in v2.0.0:
```cpp
struct EasyFileHeader {
uint32_t signature = 0;
uint32_t version = 0;
profiler::processid_t pid = 0;
int64_t cpu_frequency = 0;
profiler::timestamp_t begin_time = 0;
profiler::timestamp_t end_time = 0;

// Changed order of memory_size and blocks_number relative to v1.3.0
uint64_t memory_size = 0;
uint64_t descriptors_memory_size = 0;
uint32_t total_blocks_number = 0;
uint32_t total_descriptors_number = 0;
};
```
# License
Licensed under either of
Expand Down
10 changes: 10 additions & 0 deletions easy_profiler_converter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,13 @@ include_directories(./include)

add_executable(profiler_converter ${HEADER_FILES} ${CPP_FILES} main.cpp)
target_link_libraries(profiler_converter easy_profiler)

install(
TARGETS
profiler_converter
RUNTIME
DESTINATION
bin
)

set_property(TARGET profiler_converter PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
Loading

0 comments on commit f6d74c1

Please sign in to comment.