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

Last change on this file since 368 was 365, checked in by epyon, 10 years ago
  • overhaul of logging: no longer stream operated no longer using STL no memory allocation shorthand macros fast file and console I/O
File size: 2.9 KB
Line 
1// Copyright (C) 2012-2014 ChaosForge Ltd
2// This file is part of NV Libraries.
3// For conditions of distribution and use, see copyright notice in nv.hh
4
5#include "nv/core/profiler.hh"
6
7#include <iomanip>
8#include <ios>
9#include "nv/core/time.hh"
10#include "nv/core/logging.hh"
11
12using namespace nv;
13
14
15profiler::profiler()
16{
17        m_root = new node( "root", nullptr );
18        m_root->start();
19        m_current = m_root;
20}
21
22profiler::~profiler()
23{
24        delete m_root;
25}
26
27void profiler::start_profile( const char* tag )
28{
29        if ( tag != m_current->m_tag )
30        {
31                m_current = m_current->request_child( tag );
32        }
33        m_current->start();
34}
35
36void profiler::stop_profile()
37{
38        if ( m_current->stop() )
39        {
40                m_current = m_current->get_parent();
41        }
42}
43
44profiler::node::node( const char* tag, node* parent )
45        : m_tag( tag )
46        , m_parent( parent )
47        , m_recusion( 0 )
48        , m_calls( 0 )
49        , m_start_time_us( 0 )
50        , m_total_time_us( 0 )
51{
52
53}
54
55profiler::node* profiler::node::request_child( const char* tag )
56{
57        auto it = m_children.find( tag );
58        if ( it != m_children.end() )
59                return it->second;
60        else
61        {
62                node* result = new node( tag, this );
63                m_children[ tag ] = result;
64                return result;
65        }
66}
67
68void profiler::node::start()
69{
70        m_calls++;
71        m_recusion++;
72        if ( m_recusion == 1 )
73        {
74                m_start_time_us = get_system_us();
75        }
76}
77
78bool profiler::node::stop()
79{
80        m_recusion--;
81        if ( m_recusion == 0 )
82        {
83                uint64 stop_time_us = get_system_us();
84                uint64 elapsed_us   = stop_time_us - m_start_time_us;
85                m_total_time_us     += elapsed_us;
86                return true;
87        }
88        return false;
89}
90
91
92nv::profiler::node::~node()
93{
94        for ( const auto& pair : m_children )
95        {
96                delete pair.second;
97        }
98}
99
100void profiler::log_report()
101{
102        m_root->stop();
103        NV_LOG_INFO( "-- PROFILER REPORT -----------------------------------------" );
104        NV_LOG_STREAM( LOG_INFO, std::left << std::setw(24) << "TAG"
105                << std::setw(7) << "%PARNT"
106                << std::setw(7) << "CALLS"
107                << std::setw(10) << "TOTAL(ms)"
108                << std::setw(10) << "AVG(ms)" );
109        log_node_children( "", m_root );
110        NV_LOG_INFO( "-- PROFILER REPORT END -------------------------------------" );
111        m_root->start();
112}
113
114void profiler::log_node_children( const std::string& ind, const node* n )
115{
116        for ( const auto& pair : n->m_children )
117        {
118                const node* c = pair.second;
119                if ( c->m_calls > 0 )
120                {
121                        NV_LOG_STREAM( LOG_INFO, std::left << std::setw(24) << ind + c->m_tag
122                                << std::setw(7) << std::setprecision(2) << std::fixed << ( (double)c->m_total_time_us / (double)c->m_parent->m_total_time_us ) * 100.0
123                                << std::setw(7) << c->m_calls
124                                << std::setw(10) << std::setprecision(2) << std::fixed << c->m_total_time_us / 1000.f
125                                << std::setw(10) << std::setprecision(2) << std::fixed << ( (double)c->m_total_time_us / (double)c->m_calls ) / 1000.f
126                                );
127                        if ( c->m_children.size() > 0 )
128                        {
129                                log_node_children( ind + "-", c );
130                        }
131                }
132        }
133}
Note: See TracBrowser for help on using the repository browser.