TORCS  1.3.10
The Open Racing Car Simulator
Loading...
Searching...
No Matches
profiler.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 file : profiler.cpp
4 author : Henrik Enqvist IB (henqvist@abo.fi)
5
6 ***************************************************************************/
7
8/***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
17#ifdef PROFILER
18
19#include <algorithm>
20#include <iostream>
21#include <iomanip>
22
23#include <tgf.h>
24
25
27
28ProfileInstance::ProfileInstance(const char * pname) {
29 strncpy(this->name, pname, 255);
30 this->calls = 0;
31 this->addTime = 0.0;
32 this->totalTime = 0.0;
33 this->subTime = 0.0;
34 this->openCalls = 0;
35}
36
38
39Profiler * Profiler::profiler = NULL;
40
41Profiler::Profiler() {
42 fStartTime = GfTimeClock();
43 curProfile = NULL;
44}
45
46Profiler::~Profiler() {
47 profiler = NULL;
48}
49
50Profiler * Profiler::getInstance() {
51 if (profiler == NULL) {
52 profiler = new Profiler();
53 }
54 return profiler;
55}
56
57void Profiler::startProfile(const char * name) {
58 ProfileInstance * newProfile;
59 // find or create profile instance
60 std::vector<ProfileInstance *>::iterator iter = vecProfiles.begin();
61 std::vector<ProfileInstance *>::iterator end = vecProfiles.end();
62 for (; iter != end; ++iter) {
63 if (strncmp((*iter)->name, name, 255) == 0) {
64 newProfile = (*iter);
65 goto found;
66 }
67 }
68 newProfile = new ProfileInstance(name);
69 vecProfiles.push_back(newProfile);
70 found:
71 newProfile->tmpStart = GfTimeClock();
72 ++(newProfile->openCalls);
73 ++(newProfile->calls);
74
75 // add child and push current profile to stack
76 if (curProfile != NULL) {
77 curProfile->mapChildren.insert(std::pair<ProfileInstance*, void *>(newProfile, NULL));
78 stkProfiles.push_back(curProfile);
79 assert(stkProfiles.size() < 100);
80 }
81 curProfile = newProfile;
82}
83
84void Profiler::stopProfile() {
85 assert(curProfile != NULL);
86 assert(curProfile->openCalls > 0);
87
88 double elapsed = 0.0;
89 elapsed = GfTimeClock() - curProfile->tmpStart;
90 // add a warning if time to short
91 if (elapsed < 0.00001) {
92 this->mapWarning.insert(std::pair<ProfileInstance *, void*>(curProfile, NULL));
93 }
94 curProfile->addTime += elapsed;
95 // recursive call check
96 --(curProfile->openCalls);
97 if (curProfile->openCalls == 0) {
98 curProfile->totalTime += elapsed;
99 }
100
101 // add child time to parent
102 std::vector<ProfileInstance *>::reverse_iterator last = stkProfiles.rbegin();
103 if (last != stkProfiles.rend()) {
104 curProfile = (*last);
105 curProfile->subTime += elapsed;
106 stkProfiles.pop_back();
107 } else {
108 curProfile = NULL;
109 }
110}
111
112void Profiler::stopActiveProfiles() {
113 while (curProfile != NULL) {
114 this->stopProfile();
115 }
116}
117
118bool instanceLess(const ProfileInstance * p1, const ProfileInstance * p2) {
119 return p1->totalTime < p2->totalTime;
120}
121
122#define TRUNC(a) ( (a) < 0.001 ? 0.0 : (a) )
123
124void Profiler::printProfile() {
125 double total = GfTimeClock() - fStartTime;
126 std::cerr << "****************** PROFILE ***********************" << std::endl;
127 std::cerr << "Total : " << total << std::endl;
128 std::cerr << "| TOTAL % | OWN % | % of PA | CALLS | NAME" << std::endl;
129 std::cerr << "|---------|---------|---------|---------|---------" << std::endl;
130 sort(vecProfiles.begin(), vecProfiles.end(), instanceLess);
131 std::vector<ProfileInstance *>::reverse_iterator iter = vecProfiles.rbegin();
132 std::vector<ProfileInstance *>::reverse_iterator end = vecProfiles.rend();
133 for (; iter != end; ++iter) {
134 std::cerr << "| " << std::setprecision(3) << std::setw(7)
135 << TRUNC( (*iter)->totalTime * 100 / total )
136 << " | " << std::setprecision(3) << std::setw(7)
137 << TRUNC( ((*iter)->addTime -
138 (*iter)->subTime) * 100.0 / total )
139 << " | | "
140 << std::setw(7) << (*iter)->calls << " | " << (*iter)->name << std::endl;
141 std::map<ProfileInstance *, void*>::iterator childiter =
142 (*iter)->mapChildren.begin();
143 std::map<ProfileInstance *, void*>::iterator childend =
144 (*iter)->mapChildren.end();
145 for (; childiter != childend; ++childiter) {
146 std::cerr << "| " << std::setprecision(3) << std::setw(7)
147 << TRUNC( (*childiter).first->totalTime * 100 / total )
148 << " | " << std::setprecision(3) << std::setw(7)
149 << TRUNC( ((*childiter).first->addTime - (*childiter).first->subTime) * 100.0 / total )
150 << " | " << std::setprecision(3) << std::setw(7)
151 << TRUNC( 100 * (*childiter).first->totalTime / (*iter)->totalTime )
152 << " | " << std::setw(7) << (*childiter).first->calls
153 << " | " << (*childiter).first->name << std::endl;
154 }
155 std::cerr << "----------------------------------------------------------" << std::endl;
156 }
157 std::map<ProfileInstance *, void*>::iterator warniter = mapWarning.begin();
158 std::map<ProfileInstance *, void*>::iterator warnend = mapWarning.end();
159 for (; warniter != warnend; ++warniter) {
160 std::cerr << "Warning: Profile " << (*warniter).first->name << " may be to short" << std::endl;
161 }
162}
163
164#endif /* PROFILER */
static int last
Definition Convex.cpp:59
double GfTimeClock(void)
Get the time in seconds.
Definition os.cpp:50
The Gaming Framework API.