source: trunk/src/core/profiler.cc @ 534

Last change on this file since 534 was 534, checked in by epyon, 8 years ago

CONTINUED:

  • getting rid of size_t
  • datatypes now restricted to uint32 size
  • 64-bit compatibility
  • copyright updates where modified
File size: 3.2 KB
RevLine 
[534]1// Copyright (C) 2012-2017 ChaosForge Ltd
[395]2// http://chaosforge.org/
3//
4// This file is part of Nova libraries.
5// For conditions of distribution and use, see copying.txt file in root folder.
[150]6
[319]7#include "nv/core/profiler.hh"
[150]8
[319]9#include "nv/core/time.hh"
[365]10#include "nv/core/logging.hh"
[371]11#include <cstdio>
12#include <cstdlib>
[150]13
14using namespace nv;
15
[376]16#if NV_COMPILER == NV_MSVC
[371]17#define snprintf sprintf_s
18#endif
[150]19
20profiler::profiler()
21{
[409]22        m_root = new node( "root"_hls64, nullptr );
[150]23        m_root->start();
24        m_current = m_root;
25}
26
27profiler::~profiler()
28{
29        delete m_root;
30}
31
[409]32void profiler::start_profile( string_type&& tag )
[150]33{
34        if ( tag != m_current->m_tag )
35        {
[409]36                m_current = m_current->request_child( ::nv::move( tag ) );
[150]37        }
38        m_current->start();
39}
40
41void profiler::stop_profile()
42{
43        if ( m_current->stop() )
44        {
45                m_current = m_current->get_parent();
46        }
47}
48
[409]49profiler::node::node( string_view tag, node* parent )
50        : m_tag( ::nv::move( tag ) )
[150]51        , m_parent( parent )
52        , m_recusion( 0 )
53        , m_calls( 0 )
54        , m_start_time_us( 0 )
55        , m_total_time_us( 0 )
56{
57
58}
59
[409]60profiler::node* profiler::node::request_child( string_type&& tag )
[150]61{
[409]62        auto it = m_children.find( tag );
[150]63        if ( it != m_children.end() )
64                return it->second;
65        else
66        {
67                node* result = new node( tag, this );
[409]68                m_children.assign( ::nv::move( tag ), result );
[150]69                return result;
70        }
71}
72
73void profiler::node::start()
74{
75        m_calls++;
76        m_recusion++;
77        if ( m_recusion == 1 )
78        {
79                m_start_time_us = get_system_us();
80        }
81}
82
83bool profiler::node::stop()
84{
85        m_recusion--;
86        if ( m_recusion == 0 )
87        {
88                uint64 stop_time_us = get_system_us();
89                uint64 elapsed_us   = stop_time_us - m_start_time_us;
90                m_total_time_us     += elapsed_us;
91                return true;
92        }
93        return false;
94}
95
96
97nv::profiler::node::~node()
98{
99        for ( const auto& pair : m_children )
100        {
101                delete pair.second;
102        }
103}
104
105void profiler::log_report()
106{
107        m_root->stop();
[371]108        NV_LOG_INFO( "-- PROFILER REPORT -------------------------------------" );
109        char buffer[128];
110        snprintf( buffer, 128, "%-23s %6s %6s %9s %6s", "TAG", "%PARNT", "CALLS", "TOTAL(ms)", "AVG(ms)" );
[533]111        NV_LOG_INFO( string_view( buffer, static_cast< uint32 >( nvstrlen( buffer ) ) ) );
[371]112        log_node_children( 0, m_root );
113        NV_LOG_INFO( "-- PROFILER REPORT END ---------------------------------" );
[150]114        m_root->start();
115}
116
[371]117void profiler::log_node_children( uint32 indent, const node* n )
[150]118{
[371]119        char buffer[128];
[150]120        for ( const auto& pair : n->m_children )
121        {
122                const node* c = pair.second;
123                if ( c->m_calls > 0 )
124                {
[402]125                        f64 ftotal_time_us = static_cast<f64>( c->m_total_time_us );
126                        f64 pparent = ( ftotal_time_us / static_cast<f64>( c->m_parent->m_total_time_us ) ) * 100.f;
[380]127                        uint32 calls       = c->m_calls;
[402]128                        f64 total_ms = ftotal_time_us / 1000.f;
129                        f64 avg_ms = ( ftotal_time_us / static_cast<f64>( c->m_calls ) ) / 1000.f;
[380]130                        if ( indent > 0 ) nvmemset( buffer, '-', indent );
[371]131                        snprintf( buffer + indent, 128 - indent, "%*.*s %6.2f %6d %9.2f %6.2f", indent - 23, 23 - indent,
[409]132                                c->m_tag.data(), pparent, calls, total_ms, avg_ms );
[533]133                        NV_LOG_INFO( string_view( buffer, static_cast< uint32 >( nvstrlen( buffer ) ) ) );
[150]134                        if ( c->m_children.size() > 0 )
135                        {
[371]136                                log_node_children( indent + 1, c );
[150]137                        }
138                }
139        }
140}
Note: See TracBrowser for help on using the repository browser.