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

Last change on this file since 402 was 402, checked in by epyon, 10 years ago
  • cleanups of clang warnings (gotta love them all)
  • only nv-core for now (this will take a while for the whole source)
  • mainly C++ casts instead of C-style casts, but also a few bugs fixed!
File size: 3.2 KB
Line 
1// Copyright (C) 2012-2014 ChaosForge Ltd
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.
6
7#include "nv/core/profiler.hh"
8
9#include "nv/core/time.hh"
10#include "nv/core/logging.hh"
11#include <cstdio>
12#include <cstdlib>
13
14using namespace nv;
15
16#if NV_COMPILER == NV_MSVC
17#define snprintf sprintf_s
18#endif
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
32void profiler::start_profile( const string_view& tag )
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
49profiler::node::node( const string_view& tag, node* parent )
50        : m_tag( tag.to_string() )
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
60profiler::node* profiler::node::request_child( const string_view& tag )
61{
62        std::string stag( tag.to_string() );
63        auto it = m_children.find( stag );
64        if ( it != m_children.end() )
65                return it->second;
66        else
67        {
68                node* result = new node( tag, this );
69                m_children[ stag ] = result;
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();
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)" );
112        NV_LOG_INFO( string_view( buffer, nvstrlen( buffer ) ) );
113        log_node_children( 0, m_root );
114        NV_LOG_INFO( "-- PROFILER REPORT END ---------------------------------" );
115        m_root->start();
116}
117
118void profiler::log_node_children( uint32 indent, const node* n )
119{
120        char buffer[128];
121        for ( const auto& pair : n->m_children )
122        {
123                const node* c = pair.second;
124                if ( c->m_calls > 0 )
125                {
126                        f64 ftotal_time_us = static_cast<f64>( c->m_total_time_us );
127                        f64 pparent = ( ftotal_time_us / static_cast<f64>( c->m_parent->m_total_time_us ) ) * 100.f;
128                        uint32 calls       = c->m_calls;
129                        f64 total_ms = ftotal_time_us / 1000.f;
130                        f64 avg_ms = ( ftotal_time_us / static_cast<f64>( c->m_calls ) ) / 1000.f;
131                        if ( indent > 0 ) nvmemset( buffer, '-', indent );
132                        snprintf( buffer + indent, 128 - indent, "%*.*s %6.2f %6d %9.2f %6.2f", indent - 23, 23 - indent,
133                                c->m_tag.c_str(), pparent, calls, total_ms, avg_ms );
134                        NV_LOG_INFO( string_view( buffer, nvstrlen( buffer ) ) );
135                        if ( c->m_children.size() > 0 )
136                        {
137                                log_node_children( indent + 1, c );
138                        }
139                }
140        }
141}
Note: See TracBrowser for help on using the repository browser.