mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-28 17:28:14 +08:00
Merge branch 'develop' of https://github.com/yse/easy_profiler into develop
This commit is contained in:
commit
46a9caddb8
97
README.md
97
README.md
@ -1,14 +1,13 @@
|
|||||||
# easy_profiler [![License](https://img.shields.io/badge/license-GPL3-blue.svg)](https://github.com/yse/easy_profiler/blob/develop/COPYING)[![Build Status](https://travis-ci.org/yse/easy_profiler.svg?branch=develop)](https://travis-ci.org/yse/easy_profiler)
|
# easy_profiler [![License](https://img.shields.io/badge/license-GPL3-blue.svg)](https://github.com/yse/easy_profiler/blob/develop/COPYING)[![Build Status](https://travis-ci.org/yse/easy_profiler.svg?branch=develop)](https://travis-ci.org/yse/easy_profiler)
|
||||||
|
|
||||||
1. [About](#about)
|
1. [About](#about)
|
||||||
2. [Build](#build)
|
2. [Usage](#usage)
|
||||||
|
3. [Build](#build)
|
||||||
- [Linux](#linux)
|
- [Linux](#linux)
|
||||||
- [Windows](#windows)
|
- [Windows](#windows)
|
||||||
3. [Usage](#usage)
|
|
||||||
|
|
||||||
|
|
||||||
# About
|
# About
|
||||||
Lightweight profiler library for c++
|
Lightweight cross-platform profiler library for c++
|
||||||
|
|
||||||
You can profile any function in you code. Furthermore this library provide measuring time of any block of code.
|
You can profile any function in you code. Furthermore this library provide measuring time of any block of code.
|
||||||
For example, information for 12 millions of blocks is using less than 300Mb of memory.
|
For example, information for 12 millions of blocks is using less than 300Mb of memory.
|
||||||
@ -22,50 +21,6 @@ duration, target thread id, thread owner process id, thread owner process name.
|
|||||||
|
|
||||||
You can see the results of measuring in simple GUI application which provides full statistics and renders beautiful time-line.
|
You can see the results of measuring in simple GUI application which provides full statistics and renders beautiful time-line.
|
||||||
|
|
||||||
# Build
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
For core:
|
|
||||||
* compiler with c++11 support
|
|
||||||
* cmake 3.0 or later
|
|
||||||
|
|
||||||
For GUI:
|
|
||||||
* Qt 5.3.0 or later
|
|
||||||
|
|
||||||
## 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.
|
|
||||||
|
|
||||||
### 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"
|
|
||||||
```
|
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
First of all you can specify path to include directory which contains `include/profiler` directory.
|
First of all you can specify path to include directory which contains `include/profiler` directory.
|
||||||
@ -117,4 +72,50 @@ void foo() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# Build
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
For core:
|
||||||
|
* compiler with c++11 support
|
||||||
|
* cmake 3.0 or later
|
||||||
|
|
||||||
|
For GUI:
|
||||||
|
* Qt 5.3.0 or later
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
### 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"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[![Analytics](https://ga-beacon.appspot.com/UA-82899176-1/easy_profiler/readme)](https://github.com/yse/easy_profiler)
|
[![Analytics](https://ga-beacon.appspot.com/UA-82899176-1/easy_profiler/readme)](https://github.com/yse/easy_profiler)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
unamestr=`uname`
|
unamestr=`uname`
|
||||||
SUBDIR="./bin"
|
SUBDIR="./bin"
|
||||||
if [[ ! "$unamestr" == 'Linux' ]]; then
|
if [[ ! "$unamestr" == 'Linux' ]]; then
|
||||||
SUBDIR="./bin/Release/"
|
SUBDIR="./bin/Release/"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
DISABLED_PROF=$SUBDIR/profiler_sample_disabled_profiler
|
DISABLED_PROF=$SUBDIR/profiler_sample_disabled_profiler
|
||||||
@ -12,31 +12,46 @@ ENABLED_PROF=$SUBDIR/profiler_sample
|
|||||||
TEMP_FILE_ENABLE="enable.info"
|
TEMP_FILE_ENABLE="enable.info"
|
||||||
TEMP_FILE_DISABLE="disable.info"
|
TEMP_FILE_DISABLE="disable.info"
|
||||||
RESULT_FILE="result.csv"
|
RESULT_FILE="result.csv"
|
||||||
|
RESULT_FILE_TMP="result.csv.tmp"
|
||||||
|
|
||||||
echo "Blocks count, dT prof enabled usec, dT prof disabled usec" > $RESULT_FILE
|
HEADER="Blocks count, dT prof enabled usec, dT prof disabled usec,delta, usec/block"
|
||||||
|
|
||||||
|
#echo "Blocks count, dT prof enabled usec, dT prof disabled usec,delta, usec/block" > $RESULT_FILE
|
||||||
|
|
||||||
|
rm -rf $RESULT_FILE
|
||||||
|
|
||||||
for i in {1..9}
|
for i in {1..9}
|
||||||
do
|
do
|
||||||
OBJECTS_COUNT=$(($i*100))
|
OBJECTS_COUNT=$(($i*100))
|
||||||
for j in {10..15}
|
for j in {10..15}
|
||||||
do
|
do
|
||||||
RENDER_COUNT=$(($j*100))
|
RENDER_COUNT=$(($j*100))
|
||||||
for k in {10..15}
|
for k in {10..15}
|
||||||
do
|
do
|
||||||
MODELLING_COUNT=$(($k*100))
|
MODELLING_COUNT=$(($k*100))
|
||||||
$ENABLED_PROF $OBJECTS_COUNT $RENDER_COUNT $MODELLING_COUNT > $TEMP_FILE_ENABLE
|
$ENABLED_PROF $OBJECTS_COUNT $RENDER_COUNT $MODELLING_COUNT > $TEMP_FILE_ENABLE
|
||||||
$DISABLED_PROF $OBJECTS_COUNT $RENDER_COUNT $MODELLING_COUNT > $TEMP_FILE_DISABLE
|
$DISABLED_PROF $OBJECTS_COUNT $RENDER_COUNT $MODELLING_COUNT > $TEMP_FILE_DISABLE
|
||||||
DT_ENA=`cat $TEMP_FILE_ENABLE | grep Elapsed| awk '{print $3}'`
|
DT_ENA=`cat $TEMP_FILE_ENABLE | grep Elapsed| awk '{print $3}'`
|
||||||
N_ENA=`cat $TEMP_FILE_ENABLE | grep Blocks| awk '{print $3}'`
|
N_ENA=`cat $TEMP_FILE_ENABLE | grep Blocks| awk '{print $3}'`
|
||||||
N_DIS=`cat $TEMP_FILE_DISABLE | grep Elapsed| awk '{print $3}'`
|
N_DIS=`cat $TEMP_FILE_DISABLE | grep Elapsed| awk '{print $3}'`
|
||||||
echo $N_ENA,$DT_ENA,$N_DIS >> $RESULT_FILE
|
|
||||||
done
|
DELTA=$(($DT_ENA-$N_DIS))
|
||||||
done
|
USEC_BLOCK=`awk "BEGIN{print $DELTA/$N_ENA}"`
|
||||||
|
|
||||||
|
echo $N_ENA,$DT_ENA,$N_DIS,$DELTA,$USEC_BLOCK >> $RESULT_FILE
|
||||||
|
done
|
||||||
|
done
|
||||||
echo $i
|
echo $i
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
|
cat $RESULT_FILE | sort > $RESULT_FILE_TMP
|
||||||
|
|
||||||
|
echo $HEADER > $RESULT_FILE
|
||||||
|
cat $RESULT_FILE_TMP >> $RESULT_FILE
|
||||||
|
|
||||||
rm -rf $TEMP_FILE_ENABLE
|
rm -rf $TEMP_FILE_ENABLE
|
||||||
rm -rf $TEMP_FILE_DISABLE
|
rm -rf $TEMP_FILE_DISABLE
|
||||||
|
rm -rf $RESULT_FILE_TMP
|
||||||
|
|
||||||
echo "See result in $RESULT_FILE"
|
echo "See result in $RESULT_FILE"
|
||||||
|
@ -16,6 +16,7 @@ set(H_FILES
|
|||||||
profile_manager.h
|
profile_manager.h
|
||||||
spin_lock.h
|
spin_lock.h
|
||||||
event_trace_win.h
|
event_trace_win.h
|
||||||
|
current_time.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
#include "profile_manager.h"
|
#include "profile_manager.h"
|
||||||
|
#include "current_time.h"
|
||||||
|
|
||||||
using namespace profiler;
|
using namespace profiler;
|
||||||
|
|
||||||
|
62
src/current_time.h
Normal file
62
src/current_time.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
Lightweight profiler library for c++
|
||||||
|
Copyright(C) 2016 Sergey Yagovtsev, Victor Zarubkin
|
||||||
|
|
||||||
|
This program is free software : you can redistribute it and / or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program.If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef EASY_______CURRENT_TIME_H_____
|
||||||
|
#define EASY_______CURRENT_TIME_H_____
|
||||||
|
|
||||||
|
#include "profiler/profiler.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <Windows.h>
|
||||||
|
#else
|
||||||
|
#include <chrono>
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline profiler::timestamp_t getCurrentTime()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
//see https://msdn.microsoft.com/library/windows/desktop/dn553408(v=vs.85).aspx
|
||||||
|
LARGE_INTEGER elapsedMicroseconds;
|
||||||
|
if (!QueryPerformanceCounter(&elapsedMicroseconds))
|
||||||
|
return 0;
|
||||||
|
return (profiler::timestamp_t)elapsedMicroseconds.QuadPart;
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if (defined(__GNUC__) || defined(__ICC))
|
||||||
|
|
||||||
|
#if defined(__i386__)
|
||||||
|
unsigned long long t;
|
||||||
|
__asm__ __volatile__("rdtsc" : "=A"(t));
|
||||||
|
return t;
|
||||||
|
#elif defined(__x86_64__)
|
||||||
|
unsigned int hi, lo;
|
||||||
|
__asm__ __volatile__("rdtsc" : "=a" (lo), "=d" (hi));
|
||||||
|
return ((uint64_t)hi << 32) | lo;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
return std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||||
|
#define USE_STD_CHRONO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // EASY_______CURRENT_TIME_H_____
|
@ -31,6 +31,7 @@
|
|||||||
#include "profiler/easy_net.h"
|
#include "profiler/easy_net.h"
|
||||||
#include "profiler/easy_socket.h"
|
#include "profiler/easy_socket.h"
|
||||||
#include "event_trace_win.h"
|
#include "event_trace_win.h"
|
||||||
|
#include "current_time.h"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -556,7 +557,36 @@ uint32_t ProfileManager::dumpBlocksToStream(profiler::OStream& _outputStream)
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
_outputStream.write(CPU_FREQUENCY);
|
_outputStream.write(CPU_FREQUENCY);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#if !defined(USE_STD_CHRONO)
|
||||||
|
double g_TicksPerNanoSec;
|
||||||
|
struct timespec begints, endts;
|
||||||
|
uint64_t begin = 0, end = 0;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &begints);
|
||||||
|
begin = getCurrentTime();
|
||||||
|
volatile uint64_t i;
|
||||||
|
for (i = 0; i < 100000000; i++); /* must be CPU intensive */
|
||||||
|
end = getCurrentTime();
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endts);
|
||||||
|
struct timespec tmpts;
|
||||||
|
const int NANO_SECONDS_IN_SEC = 1000000000;
|
||||||
|
tmpts.tv_sec = endts.tv_sec - begints.tv_sec;
|
||||||
|
tmpts.tv_nsec = endts.tv_nsec - begints.tv_nsec;
|
||||||
|
if (tmpts.tv_nsec < 0) {
|
||||||
|
tmpts.tv_sec--;
|
||||||
|
tmpts.tv_nsec += NANO_SECONDS_IN_SEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t nsecElapsed = tmpts.tv_sec * 1000000000LL + tmpts.tv_nsec;
|
||||||
|
g_TicksPerNanoSec = (double)(end - begin)/(double)nsecElapsed;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int64_t cpu_frequency = int(g_TicksPerNanoSec*1000000);
|
||||||
|
_outputStream.write(cpu_frequency*1000LL);
|
||||||
|
#else
|
||||||
_outputStream.write(0LL);
|
_outputStream.write(0LL);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Write begin and end time
|
// Write begin and end time
|
||||||
|
@ -40,6 +40,7 @@ along with this program.If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline uint32_t getCurrentThreadId()
|
inline uint32_t getCurrentThreadId()
|
||||||
@ -53,20 +54,6 @@ inline uint32_t getCurrentThreadId()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline profiler::timestamp_t getCurrentTime()
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
//see https://msdn.microsoft.com/library/windows/desktop/dn553408(v=vs.85).aspx
|
|
||||||
LARGE_INTEGER elapsedMicroseconds;
|
|
||||||
if (!QueryPerformanceCounter(&elapsedMicroseconds))
|
|
||||||
return 0;
|
|
||||||
return (profiler::timestamp_t)elapsedMicroseconds.QuadPart;
|
|
||||||
#else
|
|
||||||
//std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> time_point;
|
|
||||||
return std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace profiler {
|
namespace profiler {
|
||||||
|
|
||||||
class SerializedBlock;
|
class SerializedBlock;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user