#include <hierarchical_timer.h>
Don't forget to call after() to avoid timing wrongness or assertion crashes !void myFunction() { static CHTimer myTimer("myFunction"); myTimer.before(); // some code here myTimer.after(); } *
Supports only Intel processors.
Nicolas Vizerie
Nevrax France
Definition at line 187 of file hierarchical_timer.h.
Public Types | |
| enum | TSortCriterion { NoSort, TotalTime, TotalTimeWithoutSons, MeanTime, NumVisits, MaxTime, MinTime, SortCriterionsLast } |
Public Member Functions | |
| void | after (bool displayAfter) |
| void | after () |
| void | before () |
| Starts a measuring session. | |
| CHTimer (const char *name, bool isRoot=false) | |
| CHTimer () | |
| ctor | |
| const char * | getName () const |
| void | setName (const char *name) |
Static Public Member Functions | |
| void | adjust () |
| void | bench () |
| bool | benching () |
| void | clear () |
| Clears stats, and reinits all timer structure. | |
| void | display (CLog *log=InfoLog, TSortCriterion criterion=TotalTime, bool displayInline=true, bool displayEx=true) |
| void | displayByExecutionPath (CLog *log=InfoLog, TSortCriterion criterion=TotalTime, bool displayInline=true, bool alignPaths=true, bool displayEx=true) |
| void | displayHierarchical (CLog *log=InfoLog, bool displayEx=true, uint labelNumChar=32, uint indentationStep=2) |
| void | displayHierarchicalByExecutionPath (CLog *log=InfoLog, bool displayEx=true, uint labelNumChar=32, uint indentationStep=2) |
| void | displayHierarchicalByExecutionPathSorted (CLog *log=InfoLog, TSortCriterion criterion=TotalTime, bool displayEx=true, uint labelNumChar=32, uint indentationStep=2) |
| void | displaySummary (CLog *log=InfoLog, TSortCriterion criterion=TotalTime, bool displayEx=true, uint labelNumChar=32, uint indentationStep=2, uint maxDepth=3) |
| void | endBench () |
| Ends a bench session. | |
| void | startBench (bool wantStandardDeviation=false, bool quick=false, bool reset=true) |
Private Types | |
| typedef std::vector< CNode * > | TNodeVect |
| typedef std::vector< CHTimer * > | TTimerVect |
Private Member Functions | |
| void | doAfter (bool displayAfter=false) |
| void | doBefore () |
| void | walkTreeToCurrent () |
Static Private Member Functions | |
| void | estimateAfterStopTime () |
Private Attributes | |
| bool | _IsRoot |
| const char * | _Name |
| CHTimer * | _Parent |
| TTimerVect | _Sons |
Static Private Attributes | |
| sint64 | _AfterStopEstimateTime = 0 |
| bool | _AfterStopEstimateTimeDone = false |
| bool | _Benching = false |
| bool | _BenchStartedOnce = false |
| CNode * | _CurrNode = &_RootNode |
| CHTimer * | _CurrTimer = &_RootTimer |
| double | _MsPerTick |
| CSimpleClock | _PreambuleClock |
| CNode | _RootNode |
| CHTimer | _RootTimer |
| bool | _WantStandardDeviation = false |
|
|
Definition at line 282 of file hierarchical_timer.h. Referenced by display(), displayByExecutionPath(), and displayHierarchical(). |
|
|
Definition at line 283 of file hierarchical_timer.h. |
|
|
Definition at line 191 of file hierarchical_timer.h.
00191 { NoSort,
00192 TotalTime,
00193 TotalTimeWithoutSons,
00194 MeanTime,
00195 NumVisits,
00196 MaxTime,
00197 MinTime,
00198 SortCriterionsLast
00199 };
|
|
|
ctor
Definition at line 202 of file hierarchical_timer.h. References _IsRoot.
|
|
||||||||||||
|
Definition at line 203 of file hierarchical_timer.h. References _IsRoot.
|
|
|
For backward compatibility Definition at line 234 of file hierarchical_timer.h.
00234 {}
|
|
|
Definition at line 216 of file hierarchical_timer.h. References _Benching, and doAfter().
|
|
|
Definition at line 211 of file hierarchical_timer.h. References _Benching, and doAfter(). Referenced by endBench(), estimateAfterStopTime(), NLMISC::CAutoTimer::~CAutoTimer(), and NLMISC::CAutoTimerInst::~CAutoTimerInst().
|
|
|
Starts a measuring session.
Definition at line 205 of file hierarchical_timer.h. References _Benching, and doBefore(). Referenced by NLMISC::CAutoTimer::CAutoTimer(), NLMISC::CAutoTimerInst::CAutoTimerInst(), estimateAfterStopTime(), and startBench().
|
|
|
For backward compatibility Definition at line 231 of file hierarchical_timer.h. References startBench().
00231 { startBench(); }
|
|
|
Definition at line 238 of file hierarchical_timer.h. References _Benching.
00238 { return _Benching; }
|
|
|
Clears stats, and reinits all timer structure.
Definition at line 796 of file hierarchical_timer.cpp. References _CurrNode, _RootNode, nlassert, and NLMISC::CHTimer::CNode::reset(). Referenced by estimateAfterStopTime(), and startBench().
|
|
||||||||||||||||||||
|
Display results
Definition at line 288 of file hierarchical_timer.cpp. References _BenchStartedOnce, _CurrNode, _MsPerTick, _RootNode, _WantStandardDeviation, NLMISC::CHTimer::CStats::buildFromNode(), NLMISC::CLog::displayNL(), NLMISC::CLog::displayRawNL(), format, NLMISC::CSimpleClock::getNumTicks(), NoSort, NLMISC::CHTimer::CNode::Owner, NLMISC::smprintf(), NLMISC::CHTimer::CNode::Sons, NLMISC::CHTimer::CNode::SonsPreambule, NLMISC::CSimpleClock::start(), NLMISC::CSimpleClock::stop(), TNodeVect, NLMISC::toString(), NLMISC::CHTimer::CStats::TotalTime, and uint. Referenced by NLSOUND::CSoundDriverDSound::displayBench().
00289 {
00290 CSimpleClock benchClock;
00291 benchClock.start();
00292 if(!_BenchStartedOnce) // should have done at least one bench
00293 {
00294 benchClock.stop();
00295 _CurrNode->SonsPreambule += benchClock.getNumTicks();
00296 return;
00297 }
00298 log->displayNL("HTIMER: =========================================================================");
00299 log->displayRawNL("HTIMER: Bench cumuled results");
00300 typedef std::map<CHTimer *, TNodeVect> TNodeMap;
00301 TNodeMap nodeMap;
00302 TNodeVect nodeLeft;
00303 nodeLeft.push_back(&_RootNode);
00305 while (!nodeLeft.empty())
00306 {
00307 CNode *currNode = nodeLeft.back();
00308 nodeMap[currNode->Owner].push_back(currNode);
00309 nodeLeft.pop_back();
00310 nodeLeft.insert(nodeLeft.end(), currNode->Sons.begin(), currNode->Sons.end());
00311
00312 }
00313 //
00314 // 2 ) build statistics
00315 typedef std::vector<CTimerStat> TTimerStatVect;
00316 typedef std::vector<CTimerStat *> TTimerStatPtrVect;
00317 TTimerStatVect stats(nodeMap.size());
00318 TTimerStatPtrVect statsPtr(stats.size());
00319 //
00320 uint k = 0;
00321 for(TNodeMap::iterator it = nodeMap.begin(); it != nodeMap.end(); ++it)
00322 {
00323 statsPtr[k] = &stats[k];
00324 stats[k].Timer = it->first;
00325 stats[k].buildFromNodes(&(it->second[0]), it->second.size(), _MsPerTick);
00326 ++k;
00327 }
00328 // 3 ) sort statistics
00329 if (criterion != NoSort)
00330 {
00331 CStatSorter sorter(criterion);
00332 std::sort(statsPtr.begin(), statsPtr.end(), sorter);
00333 }
00334
00335 // 4 ) get root total time.
00336 CStats rootStats;
00337 rootStats.buildFromNode( &_RootNode, _MsPerTick);
00338
00339 // 5 ) display statistics
00340 uint maxNodeLenght = 0;
00341 std::string format;
00342 if (displayInline)
00343 {
00344 for(TTimerStatPtrVect::iterator statIt = statsPtr.begin(); statIt != statsPtr.end(); ++statIt)
00345 {
00346 maxNodeLenght = std::max(maxNodeLenght, (uint)strlen((*statIt)->Timer->_Name));
00347 }
00348 format = "HTIMER: %-" + NLMISC::toString(maxNodeLenght + 1) + "s %s";
00349 }
00350 std::string statsInline;
00351
00352 log->displayRawNL(format.c_str(), "", " | total | local | visits | loc%/ glb% | min | max | mean");
00353
00354 for(TTimerStatPtrVect::iterator statIt = statsPtr.begin(); statIt != statsPtr.end(); ++statIt)
00355 {
00356 if (!displayInline)
00357 {
00358 log->displayRawNL("HTIMER: =================================");
00359 log->displayRawNL("HTIMER: Node %s", (*statIt)->Timer->_Name);
00360 (*statIt)->display(log, displayEx, _WantStandardDeviation);
00361 }
00362 else
00363 {
00364 (*statIt)->getStats(statsInline, displayEx, rootStats.TotalTime, _WantStandardDeviation);
00365 char out[4096];
00366 NLMISC::smprintf(out, 2048, format.c_str(), (*statIt)->Timer->_Name, statsInline.c_str());
00367 log->displayRawNL(out);
00368 }
00369 }
00370 benchClock.stop();
00371 _CurrNode->SonsPreambule += benchClock.getNumTicks();
00372 }
|
|
||||||||||||||||||||||||
|
Display results by execution paths
Definition at line 375 of file hierarchical_timer.cpp. References _BenchStartedOnce, _CurrNode, _MsPerTick, _RootNode, _WantStandardDeviation, NLMISC::CHTimer::CStats::buildFromNode(), NLMISC::CLog::displayRawNL(), format, NLMISC::CHTimer::CNode::getNumNodes(), NLMISC::CSimpleClock::getNumTicks(), nlassert, NoSort, NLMISC::smprintf(), NLMISC::CHTimer::CNode::Sons, NLMISC::CHTimer::CNode::SonsPreambule, NLMISC::CSimpleClock::start(), NLMISC::CSimpleClock::stop(), TNodeVect, NLMISC::toString(), NLMISC::CHTimer::CStats::TotalTime, and uint. Referenced by NLSOUND::CSoundDriverDSound::displayBench().
00376 {
00377 CSimpleClock benchClock;
00378 benchClock.start();
00379 log->displayRawNL("HTIMER: =========================================================================");
00380 log->displayRawNL("HTIMER: Bench by execution path");
00381 nlassert(_BenchStartedOnce); // should have done at least one bench
00382 //
00383 typedef std::vector<CNodeStat> TNodeStatVect;
00384 typedef std::vector<CNodeStat *> TNodeStatPtrVect;
00385
00386 TNodeStatVect nodeStats;
00387 nodeStats.reserve(_RootNode.getNumNodes());
00388 TNodeVect nodeLeft;
00389 nodeLeft.push_back(&_RootNode);
00391 while (!nodeLeft.empty())
00392 {
00393 CNode *currNode = nodeLeft.back();
00394
00395 nodeStats.push_back(CNodeStat());
00396 nodeStats.back().buildFromNode(currNode, _MsPerTick);
00397 nodeStats.back().Node = currNode;
00398
00399 nodeLeft.pop_back();
00400 nodeLeft.insert(nodeLeft.end(), currNode->Sons.begin(), currNode->Sons.end());
00401
00402 }
00403
00405 // create a pointer list
00406 TNodeStatPtrVect nodeStatsPtrs(nodeStats.size());
00407 for(uint k = 0; k < nodeStats.size(); ++k)
00408 {
00409 nodeStatsPtrs[k] = &nodeStats[k];
00410 }
00411
00412 // 3 ) sort statistics
00413 if (criterion != NoSort)
00414 {
00415 CStatSorter sorter(criterion);
00416 std::sort(nodeStatsPtrs.begin(), nodeStatsPtrs.end(), sorter);
00417 }
00418
00419 // 4 ) get root total time.
00420 CStats rootStats;
00421 rootStats.buildFromNode(&_RootNode, _MsPerTick);
00422
00423 // 5 ) display statistics
00424 std::string statsInline;
00425 std::string nodePath;
00426
00427 std::string format;
00428 if (displayInline)
00429 {
00430 if (alignPaths)
00431 {
00432 uint maxSize = 0;
00433 std::string np;
00434 for(TNodeStatPtrVect::iterator it = nodeStatsPtrs.begin(); it != nodeStatsPtrs.end(); ++it)
00435 {
00436 (*it)->Node->getPath(np);
00437 maxSize = std::max(maxSize, (uint)np.size());
00438 }
00439 format = "HTIMER: %-" + NLMISC::toString(maxSize) +"s %s";
00440 }
00441 else
00442 {
00443 format = "HTIMER: %s %s";
00444 }
00445 }
00446
00447 log->displayRawNL(format.c_str(), "", " | total | local | visits | loc%/ glb% | min | max | mean");
00448
00449 for(TNodeStatPtrVect::iterator it = nodeStatsPtrs.begin(); it != nodeStatsPtrs.end(); ++it)
00450 {
00451 if (!displayInline)
00452 {
00453 log->displayRawNL("HTIMER: =================================");
00454 (*it)->Node->displayPath(log);
00455 (*it)->display(log, displayEx, _WantStandardDeviation);
00456 }
00457 else
00458 {
00459 (*it)->getStats(statsInline, displayEx, rootStats.TotalTime, _WantStandardDeviation);
00460 (*it)->Node->getPath(nodePath);
00461
00462 char out[2048];
00463 NLMISC::smprintf(out, 2048, format.c_str(), nodePath.c_str(), statsInline.c_str());
00464 log->displayRawNL(out);
00465 }
00466 }
00467 benchClock.stop();
00468 _CurrNode->SonsPreambule += benchClock.getNumTicks();
00469 }
|
|
||||||||||||||||||||
|
Hierarchical display, no sorting is done
Definition at line 472 of file hierarchical_timer.cpp. References _BenchStartedOnce, _CurrNode, _MsPerTick, _Name, _Parent, _RootNode, _RootTimer, _Sons, _WantStandardDeviation, NLMISC::CHTimer::CStats::buildFromNode(), NLMISC::CHTimer::CStats::buildFromNodes(), depth, NLMISC::CLog::displayNL(), NLMISC::CLog::displayRawNL(), NLMISC::CSimpleClock::getNumTicks(), NLMISC::CHTimer::CStats::getStats(), min, nlassert, NLMISC::CHTimer::CNode::Owner, sint, NLMISC::CHTimer::CNode::Sons, NLMISC::CHTimer::CNode::SonsPreambule, NLMISC::CSimpleClock::start(), NLMISC::CSimpleClock::stop(), TNodeVect, NLMISC::CHTimer::CStats::TotalTime, and uint. Referenced by NLSOUND::CSoundDriverDSound::displayBench().
00473 {
00474 CSimpleClock benchClock;
00475 benchClock.start();
00476 log->displayNL("HTIMER: =========================================================================");
00477 log->displayRawNL("HTIMER: Hierarchical display of bench");
00478 nlassert(_BenchStartedOnce); // should have done at least one bench
00479 typedef std::map<CHTimer *, TNodeVect> TNodeMap;
00480 TNodeMap nodeMap;
00481 TNodeVect nodeLeft;
00482 nodeLeft.push_back(&_RootNode);
00484 while (!nodeLeft.empty())
00485 {
00486 CNode *currNode = nodeLeft.back();
00487 nodeMap[currNode->Owner].push_back(currNode);
00488 nodeLeft.pop_back();
00489 nodeLeft.insert(nodeLeft.end(), currNode->Sons.begin(), currNode->Sons.end());
00490
00491 }
00492 log->displayRawNL("HTIMER: %*s | total | local | visits | loc%%/ glb%% | min | max | mean", labelNumChar, "");
00493
00495 CStats rootStats;
00496 rootStats.buildFromNode(&_RootNode, _MsPerTick);
00497
00499 CStats currNodeStats;
00500 std::vector<uint> sonsIndex;
00501 uint depth = 0;
00502 CHTimer *currTimer = &_RootTimer;
00503 sonsIndex.push_back(0);
00504 bool displayStat = true;
00505 std::string resultName;
00506 std::string resultStats;
00507 while (!sonsIndex.empty())
00508 {
00509 if (displayStat)
00510 {
00511 resultName.resize(labelNumChar);
00512 std::fill(resultName.begin(), resultName.end(), '.');
00513 uint startIndex = depth * indentationStep;
00514 uint endIndex = std::min(startIndex + (uint)::strlen(currTimer->_Name), labelNumChar);
00515 if ((sint) (endIndex - startIndex) >= 1)
00516 {
00517 std::copy(currTimer->_Name, currTimer->_Name + (endIndex - startIndex), resultName.begin() + startIndex);
00518 }
00519 TNodeVect &execNodes = nodeMap[currTimer];
00520 if (execNodes.size() > 0)
00521 {
00522 currNodeStats.buildFromNodes(&execNodes[0], execNodes.size(), _MsPerTick);
00523 currNodeStats.getStats(resultStats, displayEx, rootStats.TotalTime, _WantStandardDeviation);
00524 log->displayRawNL("HTIMER: %s", (resultName + resultStats).c_str());
00525 }
00526 }
00527 if (sonsIndex.back() == currTimer->_Sons.size())
00528 {
00529 sonsIndex.pop_back();
00530 currTimer = currTimer->_Parent;
00531 displayStat = false;
00532 -- depth;
00533 }
00534 else
00535 {
00536 currTimer = currTimer->_Sons[sonsIndex.back()];
00537 ++ sonsIndex.back();
00538 sonsIndex.push_back(0);
00539 displayStat = true;
00540 ++ depth;
00541 }
00542 }
00543 benchClock.stop();
00544 _CurrNode->SonsPreambule += benchClock.getNumTicks();
00545 }
|
|
||||||||||||||||||||
|
Hierarchical display, no sorting is done
Definition at line 549 of file hierarchical_timer.cpp. References displayHierarchicalByExecutionPathSorted(), NoSort, and uint.
00550 {
00551 displayHierarchicalByExecutionPathSorted(log, NoSort, displayEx, labelNumChar, indentationStep);
00552 }
|
|
||||||||||||||||||||||||
|
Hierarchical display, sorting is done in branchs
Definition at line 556 of file hierarchical_timer.cpp. References _BenchStartedOnce, _CurrNode, _MsPerTick, _Name, _RootNode, _WantStandardDeviation, NLMISC::CHTimer::CStats::buildFromNode(), NLMISC::CHTimer::CStatSorter::Criterion, NLMISC::CLog::displayRawNL(), NLMISC::CSimpleClock::getNumTicks(), NLMISC::CHTimer::CStats::getStats(), min, nlassert, NoSort, NLMISC::CHTimer::CNode::Owner, sint, NLMISC::CHTimer::CNode::Sons, NLMISC::CHTimer::CNode::SonsPreambule, NLMISC::CSimpleClock::start(), NLMISC::CSimpleClock::stop(), NLMISC::CHTimer::CStats::TotalTime, and uint. Referenced by NLSOUND::CSoundDriverDSound::displayBench(), and displayHierarchicalByExecutionPath().
00557 {
00558
00559 CSimpleClock benchClock;
00560 benchClock.start();
00561 nlassert(_BenchStartedOnce); // should have done at least one bench
00562
00563 // get root total time.
00564 CStats rootStats;
00565 rootStats.buildFromNode(&_RootNode, _MsPerTick);
00566
00567
00568 // display header.
00569 CLog::TDisplayInfo dummyDspInfo;
00570 log->displayRawNL("HTIMER: =========================================================================");
00571 log->displayRawNL("HTIMER: Hierarchical display of bench by execution path");
00572 log->displayRawNL("HTIMER: %*s | total | local | visits | loc%%/ glb%% | min | max | mean", labelNumChar, "");
00573
00574
00575 // use list because vector of vector is bad.
00576 std::list< CExamStackEntry > examStack;
00577
00578 // Add the root to the stack.
00579 examStack.push_back( CExamStackEntry( &_RootNode ) );
00580 CStats currNodeStats;
00581 std::string resultName;
00582 std::string resultStats;
00583
00584 while (!examStack.empty())
00585 {
00586 CNode *node = examStack.back().Node;
00587 std::vector<CNode*> &children= examStack.back().Children;
00588 uint child = examStack.back().CurrentChild;
00589
00590 // If child 0, then must first build children info and display me.
00591 if (child == 0)
00592 {
00593 // Build Sons Infos.
00594 // ==============
00595
00596 // resize array
00597 children.resize(node->Sons.size());
00598
00599 // If no sort, easy.
00600 if(criterion == NoSort)
00601 {
00602 children= node->Sons;
00603 }
00604 // else, Sort them with criterion.
00605 else
00606 {
00607 std::vector<CNodeStat> stats;
00608 std::vector<CNodeStat *> ptrStats;
00609 stats.resize(children.size());
00610 ptrStats.resize(children.size());
00611
00612 // build stats.
00613 uint i;
00614 for(i=0; i<children.size(); i++)
00615 {
00616 CNode *childNode= node->Sons[i];
00617 stats[i].buildFromNode(childNode, _MsPerTick);
00618 stats[i].Node = childNode;
00619 ptrStats[i]= &stats[i];
00620 }
00621
00622 // sort.
00623 CStatSorter sorter;
00624 sorter.Criterion= criterion;
00625 std::sort(ptrStats.begin(), ptrStats.end(), sorter);
00626
00627 // fill children.
00628 for(i=0; i<children.size(); i++)
00629 {
00630 children[i]= ptrStats[i]->Node;
00631 }
00632 }
00633
00634
00635 // Display our infos
00636 // ==============
00637 // build the indented node name.
00638 resultName.resize(labelNumChar);
00639 std::fill(resultName.begin(), resultName.end(), '.');
00640 uint startIndex = (examStack.size()-1) * indentationStep;
00641 uint endIndex = std::min(startIndex + (uint)::strlen(node->Owner->_Name), labelNumChar);
00642 if ((sint) (endIndex - startIndex) >= 1)
00643 {
00644 std::copy(node->Owner->_Name, node->Owner->_Name + (endIndex - startIndex), resultName.begin() + startIndex);
00645 }
00646
00647 // build the stats string.
00648 currNodeStats.buildFromNode(node, _MsPerTick);
00649 currNodeStats.getStats(resultStats, displayEx, rootStats.TotalTime, _WantStandardDeviation);
00650
00651 // display
00652 log->displayRawNL("HTIMER: %s", (resultName + resultStats).c_str());
00653 }
00654
00655 // End of sons?? stop.
00656 if (child >= children.size())
00657 {
00658 examStack.pop_back();
00659 continue;
00660 }
00661
00662 // next son.
00663 ++(examStack.back().CurrentChild);
00664
00665 // process the current son.
00666 examStack.push_back( CExamStackEntry( children[child] ) );
00667 }
00668
00669 //
00670 benchClock.stop();
00671 _CurrNode->SonsPreambule += benchClock.getNumTicks();
00672 }
|
|
||||||||||||||||||||||||||||
|
Hierarchical display, sorting is done in branchs
Definition at line 675 of file hierarchical_timer.cpp. References _BenchStartedOnce, _CurrNode, _MsPerTick, _Name, _RootNode, _WantStandardDeviation, NLMISC::CHTimer::CStats::buildFromNode(), NLMISC::CHTimer::CStatSorter::Criterion, depth, NLMISC::CLog::displayRawNL(), NLMISC::CSimpleClock::getNumTicks(), NLMISC::CHTimer::CStats::getStats(), min, nlassert, NoSort, NLMISC::CHTimer::CNode::Owner, sint, NLMISC::CHTimer::CNode::Sons, NLMISC::CHTimer::CNode::SonsPreambule, NLMISC::CSimpleClock::start(), NLMISC::CSimpleClock::stop(), NLMISC::CHTimer::CStats::TotalTime, and uint.
00676 {
00677
00678 CSimpleClock benchClock;
00679 benchClock.start();
00680 nlassert(_BenchStartedOnce); // should have done at least one bench
00681
00682 // get root total time.
00683 CStats rootStats;
00684 rootStats.buildFromNode(&_RootNode, _MsPerTick);
00685
00686
00687 // display header.
00688 CLog::TDisplayInfo dummyDspInfo;
00689 log->displayRawNL("HTIMER: =========================================================================");
00690 log->displayRawNL("HTIMER: Hierarchical display of bench by execution path");
00691 log->displayRawNL("HTIMER: %*s | total | local | visits | loc%%/ glb%% | min | max | mean", labelNumChar, "");
00692
00693
00694 // use list because vector of vector is bad.
00695 std::list< CExamStackEntry > examStack;
00696
00697 // Add the root to the stack.
00698 examStack.push_back( CExamStackEntry( &_RootNode ) );
00699 CStats currNodeStats;
00700 std::string resultName;
00701 std::string resultStats;
00702
00703 while (!examStack.empty())
00704 {
00705 CNode *node = examStack.back().Node;
00706 std::vector<CNode*> &children= examStack.back().Children;
00707 uint child = examStack.back().CurrentChild;
00708 uint depth = examStack.back().Depth;
00709
00710 // If child 0, then must first build children info and display me.
00711 if (child == 0)
00712 {
00713 // Build Sons Infos.
00714 // ==============
00715
00716 // resize array
00717 children.resize(node->Sons.size());
00718
00719 // If no sort, easy.
00720 if(criterion == NoSort)
00721 {
00722 children= node->Sons;
00723 }
00724 // else, Sort them with criterion.
00725 else
00726 {
00727 std::vector<CNodeStat> stats;
00728 std::vector<CNodeStat *> ptrStats;
00729 stats.resize(children.size());
00730 ptrStats.resize(children.size());
00731
00732 // build stats.
00733 uint i;
00734 for(i=0; i<children.size(); i++)
00735 {
00736 CNode *childNode= node->Sons[i];
00737 stats[i].buildFromNode(childNode, _MsPerTick);
00738 stats[i].Node = childNode;
00739 ptrStats[i]= &stats[i];
00740 }
00741
00742 // sort.
00743 CStatSorter sorter;
00744 sorter.Criterion= criterion;
00745 std::sort(ptrStats.begin(), ptrStats.end(), sorter);
00746
00747 // fill children.
00748 for(i=0; i<children.size(); i++)
00749 {
00750 children[i]= ptrStats[i]->Node;
00751 }
00752 }
00753
00754
00755 // Display our infos
00756 // ==============
00757 // build the indented node name.
00758 resultName.resize(labelNumChar);
00759 std::fill(resultName.begin(), resultName.end(), '.');
00760 uint startIndex = (examStack.size()-1) * indentationStep;
00761 uint endIndex = std::min(startIndex + (uint)::strlen(node->Owner->_Name), labelNumChar);
00762 if ((sint) (endIndex - startIndex) >= 1)
00763 {
00764 std::copy(node->Owner->_Name, node->Owner->_Name + (endIndex - startIndex), resultName.begin() + startIndex);
00765 }
00766
00767 // build the stats string.
00768 currNodeStats.buildFromNode(node, _MsPerTick);
00769 currNodeStats.getStats(resultStats, displayEx, rootStats.TotalTime, _WantStandardDeviation);
00770
00771 // display
00772 log->displayRawNL("HTIMER: %s", (resultName + resultStats).c_str());
00773 }
00774
00775 // End of sons?? stop.
00776 if (child >= children.size())
00777 {
00778 examStack.pop_back();
00779 continue;
00780 }
00781
00782 // next son.
00783 ++(examStack.back().CurrentChild);
00784
00785 // process the current son.
00786 if (depth+1 < maxDepth)
00787 examStack.push_back( CExamStackEntry( children[child], depth+1 ) );
00788 }
00789
00790 //
00791 benchClock.stop();
00792 _CurrNode->SonsPreambule += benchClock.getNumTicks();
00793 }
|
|
|
Definition at line 957 of file hierarchical_timer.cpp. References _AfterStopEstimateTime, _CurrNode, _CurrTimer, _MsPerTick, _PreambuleClock, _WantStandardDeviation, NLMISC::CHTimer::CNode::Clock, NLMISC::CSimpleClock::getNumTicks(), NLMISC::CHTimer::CNode::LastSonsTotalTime, NLMISC::CHTimer::CNode::MaxTime, NLMISC::CHTimer::CNode::Measures, min, NLMISC::CHTimer::CNode::MinTime, nlinfo, NLMISC::CHTimer::CNode::NumVisits, NLMISC::CHTimer::CNode::Parent, sint64, NLMISC::CHTimer::CNode::SonsPreambule, NLMISC::CHTimer::CNode::SonsTotalTime, NLMISC::CSimpleClock::start(), NLMISC::CSimpleClock::stop(), NLMISC::CHTimer::CNode::TotalTime, and uint64. Referenced by after().
00958 {
00959 _CurrNode->Clock.stop();
00960 _PreambuleClock.start();
00961 /* Remove my Son preambule, and remove only ONE StartStop
00962 It is because between the start and the end, only ONE rdtsc time is counted:
00963 */
00964 sint64 numTicks = _CurrNode->Clock.getNumTicks() - _CurrNode->SonsPreambule - (CSimpleClock::getStartStopNumTicks());
00965 // Case where the SonPreambule is overestimated,
00966 numTicks= std::max((sint64)0, numTicks);
00967 // In case where the SonPreambule is overestimated, the TotalTime must not be < of the SonTime
00968 if(_CurrNode->TotalTime + numTicks < _CurrNode->SonsTotalTime)
00969 numTicks= _CurrNode->SonsTotalTime - _CurrNode->TotalTime;
00970
00971 _CurrNode->TotalTime += numTicks;
00972 _CurrNode->MinTime = std::min(_CurrNode->MinTime, (uint64)numTicks);
00973 _CurrNode->MaxTime = std::max(_CurrNode->MaxTime, (uint64)numTicks);
00974 _CurrNode->LastSonsTotalTime = _CurrNode->SonsTotalTime;
00975
00976 if (displayAfter)
00977 {
00978 nlinfo("HTIMER: %s %.3fms loop number %d", _Name, numTicks * _MsPerTick, _CurrNode->NumVisits);
00979 }
00980 //
00981 if (_WantStandardDeviation)
00982 {
00983 _CurrNode->Measures.push_back(numTicks * _MsPerTick);
00984 }
00985 //
00986 if (_Parent)
00987 {
00988 _CurrTimer = _Parent;
00989 }
00990 //
00991 if (_CurrNode->Parent)
00992 {
00993 CNode *curNode= _CurrNode;
00994 CNode *parent= _CurrNode->Parent;
00995 parent->SonsTotalTime += numTicks;
00996 _PreambuleClock.stop();
00997 /*
00998 The SonPreambule of my parent is
00999 + my BeforePreambule (counted in doBefore)
01000 + my Afterpreambule (see below)
01001 + my Sons Preambule
01002 + some constant time due to the Start/Stop of the _CurrNode->Clock, the 2* Start/Stop
01003 of the PreabmuleClock, the function call time of doBefore and doAfter
01004 */
01005 parent->SonsPreambule += _PreambuleClock.getNumTicks() + curNode->SonsPreambule + _AfterStopEstimateTime;
01006 // walk to parent
01007 _CurrNode= parent;
01008 }
01009 else
01010 {
01011 _PreambuleClock.stop();
01012 }
01013 }
|
|
|
Definition at line 935 of file hierarchical_timer.cpp. References _CurrNode, _CurrTimer, _PreambuleClock, _Sons, NLMISC::CHTimer::CNode::Clock, NLMISC::CSimpleClock::getNumTicks(), NLMISC::CHTimer::CNode::NumVisits, NLMISC::CHTimer::CNode::Parent, NLMISC::CHTimer::CNode::SonsPreambule, NLMISC::CSimpleClock::start(), NLMISC::CSimpleClock::stop(), and walkTreeToCurrent(). Referenced by before().
00936 {
00937 _PreambuleClock.start();
00938 walkTreeToCurrent();
00939 ++ _CurrNode->NumVisits;
00940 _CurrNode->SonsPreambule = 0;
00941 if (!_Parent && _CurrTimer != this)
00942 {
00943 _Parent = _CurrTimer;
00944 // register as a son of the parent
00945 _Parent->_Sons.push_back(this);
00946 }
00947 _CurrTimer = this;
00948 _PreambuleClock.stop();
00949 if (_CurrNode->Parent)
00950 {
00951 _CurrNode->Parent->SonsPreambule += _PreambuleClock.getNumTicks();
00952 }
00953 _CurrNode->Clock.start();
00954 }
|
|
|
Ends a bench session.
Definition at line 271 of file hierarchical_timer.cpp. References _Benching, _CurrNode, _RootNode, _RootTimer, after(), and nlwarning. Referenced by NLSOUND::CSoundDriverDSound::endBench().
|
|
|
Definition at line 194 of file hierarchical_timer.cpp. References _AfterStopEstimateTime, _AfterStopEstimateTimeDone, _Benching, _BenchStartedOnce, _MsPerTick, _RootNode, _RootTimer, _WantStandardDeviation, after(), before(), clear(), NLMISC::CHTimer::CNode::Owner, NLMISC::CHTimer::CNode::SonsTotalTime, NLMISC::CHTimer::CNode::TotalTime, and uint. Referenced by startBench().
00195 {
00196 if(_AfterStopEstimateTimeDone)
00197 return;
00198 const uint numSamples = 1000;
00199
00200 // Do as in startBench, reset and init
00201 clear();
00202
00203 {
00204 #ifdef NL_CPU_INTEL
00205 double freq = (double) CSystemInfo::getProcessorFrequency(false);
00206 _MsPerTick = 1000 / (double) freq;
00207 #else
00208 _MsPerTick = CTime::ticksToSecond(1000);
00209 #endif
00210 CSimpleClock::init();
00211 }
00212
00213 // start
00214 _Benching = true;
00215 _BenchStartedOnce = true;
00216 _RootNode.Owner = &_RootTimer;
00217 _WantStandardDeviation = false;
00218 _RootTimer.before();
00219
00220 for(uint i=0;i<numSamples;i++)
00221 {
00222 static NLMISC::CHTimer estimateSampleTimer("sampleTimer");
00223 estimateSampleTimer.before();
00224 estimateSampleTimer.after();
00225 }
00226
00227 _RootTimer.after();
00228 _Benching = false;
00229
00230 // Then the After Stop time is the rootTimer time / numSamples
00231 _AfterStopEstimateTime= (_RootNode.TotalTime-_RootNode.SonsTotalTime) / numSamples;
00232
00233 _AfterStopEstimateTimeDone= true;
00234
00235 // must re-clear.
00236 clear();
00237 }
|
|
|
Definition at line 222 of file hierarchical_timer.h. Referenced by NLMISC::CHTimer::CNode::getPath().
00222 { return _Name; }
|
|
|
Definition at line 223 of file hierarchical_timer.h.
00223 { _Name = name; }
|
|
||||||||||||||||
|
Starts a bench session
Definition at line 241 of file hierarchical_timer.cpp. References _Benching, _BenchStartedOnce, _MsPerTick, _RootNode, _RootTimer, _WantStandardDeviation, before(), clear(), estimateAfterStopTime(), nlassert, and NLMISC::CHTimer::CNode::Owner. Referenced by bench(), and NLSOUND::CSoundDriverDSound::startBench().
00242 {
00243 nlassert(!_Benching);
00244
00245 // if not done, estimate the AfterStopTime
00246 estimateAfterStopTime();
00247
00248 if(reset)
00249 clear();
00250
00251 if(reset)
00252 {
00253 #ifdef NL_CPU_INTEL
00254 double freq = (double) CSystemInfo::getProcessorFrequency(quick);
00255 _MsPerTick = 1000 / (double) freq;
00256 #else
00257 _MsPerTick = CTime::ticksToSecond(1000);
00258 #endif
00259 CSimpleClock::init();
00260 }
00261
00262 // Launch
00263 _Benching = true;
00264 _BenchStartedOnce = true;
00265 _RootNode.Owner = &_RootTimer;
00266 _WantStandardDeviation = wantStandardDeviation;
00267 _RootTimer.before();
00268 }
|
|
|
Definition at line 169 of file hierarchical_timer.cpp. References _CurrNode, _IsRoot, NLMISC::CHTimer::CNode::Sons, and uint. Referenced by doBefore().
00170 {
00171 if (_IsRoot) return;
00172 bool found = false;
00173 for(uint k = 0; k < _CurrNode->Sons.size(); ++k)
00174 {
00175 if (_CurrNode->Sons[k]->Owner == this)
00176 {
00177 _CurrNode = _CurrNode->Sons[k];
00178 found = true;
00179 break;
00180 }
00181 }
00182 if (!found)
00183 {
00184 // no node for this execution path : create a new one
00185 _CurrNode->Sons.push_back(new CNode(this, _CurrNode));
00186 _CurrNode->Sons.back()->Parent = _CurrNode;
00187 _CurrNode = _CurrNode->Sons.back();
00188 }
00189 }
|
|
|
Definition at line 57 of file hierarchical_timer.cpp. Referenced by doAfter(), and estimateAfterStopTime(). |
|
|
Definition at line 58 of file hierarchical_timer.cpp. Referenced by estimateAfterStopTime(). |
|
|
Definition at line 52 of file hierarchical_timer.cpp. Referenced by after(), before(), benching(), endBench(), estimateAfterStopTime(), and startBench(). |
|
|
Definition at line 53 of file hierarchical_timer.cpp. Referenced by display(), displayByExecutionPath(), displayHierarchical(), displayHierarchicalByExecutionPathSorted(), displaySummary(), estimateAfterStopTime(), and startBench(). |
|
|
Definition at line 49 of file hierarchical_timer.cpp. Referenced by clear(), display(), displayByExecutionPath(), displayHierarchical(), displayHierarchicalByExecutionPathSorted(), displaySummary(), doAfter(), doBefore(), endBench(), and walkTreeToCurrent(). |
|
|
Definition at line 56 of file hierarchical_timer.cpp. Referenced by doAfter(), and doBefore(). |
|
|
Definition at line 430 of file hierarchical_timer.h. Referenced by CHTimer(), and walkTreeToCurrent(). |
|
|
Definition at line 54 of file hierarchical_timer.cpp. Referenced by display(), displayByExecutionPath(), displayHierarchical(), displayHierarchicalByExecutionPathSorted(), displaySummary(), doAfter(), estimateAfterStopTime(), and startBench(). |
|
|
Definition at line 424 of file hierarchical_timer.h. Referenced by displayHierarchical(), displayHierarchicalByExecutionPathSorted(), and displaySummary(). |
|
|
Definition at line 426 of file hierarchical_timer.h. Referenced by displayHierarchical(). |
|
|
This clock is used to measure the preambule of methods such as CHTimer::before() This is static, but the Hierarchical Timer doesn't support multithreading anyway.. Definition at line 50 of file hierarchical_timer.cpp. Referenced by doAfter(), and doBefore(). |
|
|
Definition at line 48 of file hierarchical_timer.cpp. Referenced by clear(), display(), displayByExecutionPath(), displayHierarchical(), displayHierarchicalByExecutionPathSorted(), displaySummary(), endBench(), estimateAfterStopTime(), and startBench(). |
|
|
Referenced by displayHierarchical(), endBench(), estimateAfterStopTime(), and startBench(). |
|
|
Definition at line 428 of file hierarchical_timer.h. Referenced by displayHierarchical(), and doBefore(). |
|
|
Definition at line 55 of file hierarchical_timer.cpp. Referenced by display(), displayByExecutionPath(), displayHierarchical(), displayHierarchicalByExecutionPathSorted(), displaySummary(), doAfter(), estimateAfterStopTime(), and startBench(). |
1.3.6