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

Last change on this file since 395 was 395, checked in by epyon, 10 years ago
  • bulk update copyright update include guards cleanup core/common.hh -> common.hh minor cleanups
File size: 3.1 KB
RevLine 
[319]1// Copyright (C) 2012-2014 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{
22        m_root = new node( "root", nullptr );
23        m_root->start();
24        m_current = m_root;
25}
26
27profiler::~profiler()
28{
29        delete m_root;
30}
31
[371]32void profiler::start_profile( const string_ref& tag )
[150]33{
34        if ( tag != m_current->m_tag )
35        {
36                m_current = m_current->request_child( tag );
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
[371]49profiler::node::node( const string_ref& tag, node* parent )
50        : m_tag( tag.to_string() )
[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
[371]60profiler::node* profiler::node::request_child( const string_ref& tag )
[150]61{
[371]62        std::string stag( tag.to_string() );
63        auto it = m_children.find( stag );
[150]64        if ( it != m_children.end() )
65                return it->second;
66        else
67        {
68                node* result = new node( tag, this );
[371]69                m_children[ stag ] = result;
[150]70                return result;
71        }
72}
73
74void profiler::node::start()
75{
76        m_calls++;
77        m_recusion++;
78        if ( m_recusion == 1 )
79        {
80                m_start_time_us = get_system_us();
81        }
82}
83
84bool profiler::node::stop()
85{
86        m_recusion--;
87        if ( m_recusion == 0 )
88        {
89                uint64 stop_time_us = get_system_us();
90                uint64 elapsed_us   = stop_time_us - m_start_time_us;
91                m_total_time_us     += elapsed_us;
92                return true;
93        }
94        return false;
95}
96
97
98nv::profiler::node::~node()
99{
100        for ( const auto& pair : m_children )
101        {
102                delete pair.second;
103        }
104}
105
106void profiler::log_report()
107{
108        m_root->stop();
[371]109        NV_LOG_INFO( "-- PROFILER REPORT -------------------------------------" );
110        char buffer[128];
111        snprintf( buffer, 128, "%-23s %6s %6s %9s %6s", "TAG", "%PARNT", "CALLS", "TOTAL(ms)", "AVG(ms)" );
[380]112        NV_LOG_INFO( string_ref( buffer, nvstrlen( buffer ) ) );
[371]113        log_node_children( 0, m_root );
114        NV_LOG_INFO( "-- PROFILER REPORT END ---------------------------------" );
[150]115        m_root->start();
116}
117
[371]118void profiler::log_node_children( uint32 indent, const node* n )
[150]119{
[371]120        char buffer[128];
[150]121        for ( const auto& pair : n->m_children )
122        {
123                const node* c = pair.second;
124                if ( c->m_calls > 0 )
125                {
[380]126                        f64 pparent = ( (f64)c->m_total_time_us / (f64)c->m_parent->m_total_time_us ) * 100.f;
127                        uint32 calls       = c->m_calls;
128                        f64 total_ms = c->m_total_time_us / 1000.f;
129                        f64 avg_ms = ( (f64)c->m_total_time_us / (f64)c->m_calls ) / 1000.f;
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,
132                                c->m_tag.c_str(), pparent, calls, total_ms, avg_ms );
[380]133                        NV_LOG_INFO( string_ref( buffer, 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.