2017-10-01 11:37:04 +02:00
|
|
|
#include "externals.hh"
|
|
|
|
#include "utilities.hh"
|
|
|
|
#include "profiling.hh"
|
|
|
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
|
|
|
|
T_Profiler T_Profiler::Profiler;
|
|
|
|
|
2017-10-01 12:48:55 +02:00
|
|
|
constexpr uint32_t T_Profiler::Samples;
|
|
|
|
constexpr uint32_t T_Profiler::History;
|
|
|
|
constexpr uint32_t T_Profiler::Invalid;
|
|
|
|
|
2017-10-01 11:37:04 +02:00
|
|
|
|
|
|
|
void T_Profiler::clear( )
|
|
|
|
{
|
|
|
|
sections_.clear( );
|
|
|
|
samples_.clear( );
|
|
|
|
starts_.clear( );
|
|
|
|
}
|
|
|
|
|
|
|
|
void T_Profiler::startFrame( )
|
|
|
|
{
|
2017-10-01 12:48:55 +02:00
|
|
|
previous_ = Invalid;
|
|
|
|
current_ = Invalid;
|
|
|
|
}
|
|
|
|
|
|
|
|
void T_Profiler::endFrame( )
|
|
|
|
{
|
|
|
|
const auto n( sections_.size( ) );
|
|
|
|
while ( secDurations_.size( ) < n ) {
|
|
|
|
secDurations_.push_back( 0 );
|
|
|
|
secStarts_.push_back( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( auto i = 0u ; i < n ; i ++ ) {
|
|
|
|
const float d = computeDuration( i );
|
|
|
|
secDurations_[ i ] = d;
|
|
|
|
if ( parents_[ i ] != Invalid ) {
|
|
|
|
assert( parents_[ i ] < i );
|
|
|
|
secStarts_[ i ] = secStarts_[ parents_[ i ] ];
|
|
|
|
} else if ( chain_[ i ] != Invalid ) {
|
|
|
|
assert( chain_[ i ] < i );
|
|
|
|
secStarts_[ i ] = secStarts_[ chain_[ i ] ]
|
|
|
|
+ secDurations_[ chain_[ i ] ];
|
|
|
|
} else {
|
|
|
|
secStarts_[ i ] = 0;
|
|
|
|
}
|
|
|
|
}
|
2017-10-01 11:37:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void T_Profiler::start(
|
|
|
|
__rd__ std::string const& section )
|
|
|
|
{
|
|
|
|
const auto n( sections_.size( ) );
|
|
|
|
const auto pos( find( section ) );
|
|
|
|
if ( pos == n ) {
|
|
|
|
sections_.push_back( section );
|
|
|
|
samples_.push_back( T_SamplesList_{ } );
|
|
|
|
starts_.push_back( 0u );
|
2017-10-01 12:48:55 +02:00
|
|
|
chain_.push_back( Invalid );
|
|
|
|
parents_.push_back( Invalid );
|
2017-10-01 11:37:04 +02:00
|
|
|
}
|
|
|
|
|
2017-10-01 12:48:55 +02:00
|
|
|
chain_[ pos ] = previous_;
|
|
|
|
if ( current_ != Invalid ) {
|
|
|
|
parents_[ pos ] = current_;
|
|
|
|
previous_ = Invalid;
|
|
|
|
} else {
|
|
|
|
parents_[ pos ] = Invalid;
|
|
|
|
}
|
|
|
|
current_ = pos;
|
|
|
|
|
2017-10-01 11:37:04 +02:00
|
|
|
struct timespec ts;
|
|
|
|
clock_gettime( CLOCK_MONOTONIC , &ts );
|
|
|
|
starts_[ pos ] = ts.tv_sec * 1000000000 + ts.tv_nsec;
|
|
|
|
}
|
|
|
|
|
|
|
|
void T_Profiler::end(
|
|
|
|
__rd__ std::string const& section )
|
|
|
|
{
|
|
|
|
const auto pos( find( section ) );
|
|
|
|
const auto n( sections_.size( ) );
|
|
|
|
if ( pos == n ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct timespec ts;
|
|
|
|
clock_gettime( CLOCK_MONOTONIC , &ts );
|
|
|
|
|
|
|
|
const uint64_t ended = ts.tv_sec * 1000000000 + ts.tv_nsec;
|
|
|
|
const uint64_t duration = ended - starts_[ pos ];
|
|
|
|
auto& samples( samples_[ pos ] );
|
|
|
|
if ( samples.size( ) == 0 || ( samples.size( ) < History
|
|
|
|
&& samples[ 0 ].nSamples == Samples ) ) {
|
|
|
|
samples.insert( samples.begin( ) , T_ProfilerSamples{ 0 , 0 } );
|
|
|
|
} else if ( samples.size( ) == History && samples[ 0 ].nSamples == Samples ) {
|
|
|
|
for ( auto i = 1u ; i < History ; i ++ ) {
|
|
|
|
samples[ i ] = samples[ i - 1 ];
|
|
|
|
}
|
|
|
|
samples[ 0 ].sum = 0;
|
|
|
|
samples[ 0 ].nSamples = 0;
|
|
|
|
}
|
|
|
|
samples[ 0 ].sum += float( duration ) * 1e-6;
|
|
|
|
samples[ 0 ].nSamples ++;
|
2017-10-01 12:48:55 +02:00
|
|
|
|
|
|
|
previous_ = pos;
|
|
|
|
current_ = Invalid;
|
2017-10-01 11:37:04 +02:00
|
|
|
}
|
|
|
|
|
2017-10-01 12:48:55 +02:00
|
|
|
float T_Profiler::computeDuration(
|
2017-10-01 11:37:04 +02:00
|
|
|
__rd__ const uint32_t section ) const
|
|
|
|
{
|
|
|
|
auto const& samples( samples_[ section ] );
|
|
|
|
float total = 0;
|
|
|
|
float nSamples = 0;
|
|
|
|
for ( auto const& entry : samples ) {
|
|
|
|
total += entry.sum;
|
|
|
|
nSamples += entry.nSamples;
|
|
|
|
}
|
|
|
|
return total / nSamples;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t T_Profiler::find(
|
|
|
|
__rd__ std::string const& section ) const
|
|
|
|
{
|
|
|
|
const auto n( sections_.size( ) );
|
|
|
|
auto pos( 0u );
|
|
|
|
while ( pos < n && sections_[ pos ] != section ) {
|
|
|
|
pos ++;
|
|
|
|
}
|
|
|
|
return pos;
|
|
|
|
}
|