#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(). |