PageRenderTime 40ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llcommon/llstat.h

https://bitbucket.org/lindenlab/viewer-beta/
C Header | 353 lines | 222 code | 75 blank | 56 comment | 2 complexity | 3fa383114be0261e500615aa102439eb MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llstat.h
  3. * @brief Runtime statistics accumulation.
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef LL_LLSTAT_H
  27. #define LL_LLSTAT_H
  28. #include <deque>
  29. #include <map>
  30. #include "lltimer.h"
  31. #include "llframetimer.h"
  32. #include "llfile.h"
  33. class LLSD;
  34. // Set this if longer stats are needed
  35. #define ENABLE_LONG_TIME_STATS 0
  36. //
  37. // Accumulates statistics for an arbitrary length of time.
  38. // Does this by maintaining a chain of accumulators, each one
  39. // accumulation the results of the parent. Can scale to arbitrary
  40. // amounts of time with very low memory cost.
  41. //
  42. class LL_COMMON_API LLStatAccum
  43. {
  44. protected:
  45. LLStatAccum(bool use_frame_timer);
  46. virtual ~LLStatAccum();
  47. public:
  48. enum TimeScale {
  49. SCALE_100MS,
  50. SCALE_SECOND,
  51. SCALE_MINUTE,
  52. #if ENABLE_LONG_TIME_STATS
  53. SCALE_HOUR,
  54. SCALE_DAY,
  55. SCALE_WEEK,
  56. #endif
  57. NUM_SCALES, // Use to size storage arrays
  58. SCALE_PER_FRAME // For latest frame information - should be after NUM_SCALES since this doesn't go into the time buckets
  59. };
  60. static U64 sScaleTimes[NUM_SCALES];
  61. virtual F32 meanValue(TimeScale scale) const;
  62. // see the subclasses for the specific meaning of value
  63. F32 meanValueOverLast100ms() const { return meanValue(SCALE_100MS); }
  64. F32 meanValueOverLastSecond() const { return meanValue(SCALE_SECOND); }
  65. F32 meanValueOverLastMinute() const { return meanValue(SCALE_MINUTE); }
  66. void reset(U64 when);
  67. void sum(F64 value);
  68. void sum(F64 value, U64 when);
  69. U64 getCurrentUsecs() const;
  70. // Get current microseconds based on timer type
  71. BOOL mUseFrameTimer;
  72. BOOL mRunning;
  73. U64 mLastTime;
  74. struct Bucket
  75. {
  76. Bucket() :
  77. accum(0.0),
  78. endTime(0),
  79. lastValid(false),
  80. lastAccum(0.0)
  81. {}
  82. F64 accum;
  83. U64 endTime;
  84. bool lastValid;
  85. F64 lastAccum;
  86. };
  87. Bucket mBuckets[NUM_SCALES];
  88. BOOL mLastSampleValid;
  89. F64 mLastSampleValue;
  90. };
  91. class LL_COMMON_API LLStatMeasure : public LLStatAccum
  92. // gathers statistics about things that are measured
  93. // ex.: tempature, time dilation
  94. {
  95. public:
  96. LLStatMeasure(bool use_frame_timer = true);
  97. void sample(F64);
  98. void sample(S32 v) { sample((F64)v); }
  99. void sample(U32 v) { sample((F64)v); }
  100. void sample(S64 v) { sample((F64)v); }
  101. void sample(U64 v) { sample((F64)v); }
  102. };
  103. class LL_COMMON_API LLStatRate : public LLStatAccum
  104. // gathers statistics about things that can be counted over time
  105. // ex.: LSL instructions executed, messages sent, simulator frames completed
  106. // renders it in terms of rate of thing per second
  107. {
  108. public:
  109. LLStatRate(bool use_frame_timer = true);
  110. void count(U32);
  111. // used to note that n items have occured
  112. void mark();
  113. // used for counting the rate thorugh a point in the code
  114. };
  115. class LL_COMMON_API LLStatTime : public LLStatAccum
  116. // gathers statistics about time spent in a block of code
  117. // measure average duration per second in the block
  118. {
  119. public:
  120. LLStatTime( const std::string & key = "undefined" );
  121. U32 mFrameNumber; // Current frame number
  122. U64 mTotalTimeInFrame; // Total time (microseconds) accumulated during the last frame
  123. void setKey( const std::string & key ) { mKey = key; };
  124. virtual F32 meanValue(TimeScale scale) const;
  125. private:
  126. void start(); // Start and stop measuring time block
  127. void stop();
  128. std::string mKey; // Tag representing this time block
  129. #if LL_DEBUG
  130. BOOL mRunning; // TRUE if start() has been called
  131. #endif
  132. friend class LLPerfBlock;
  133. };
  134. // ----------------------------------------------------------------------------
  135. // Use this class on the stack to record statistics about an area of code
  136. class LL_COMMON_API LLPerfBlock
  137. {
  138. public:
  139. struct StatEntry
  140. {
  141. StatEntry(const std::string& key) : mStat(LLStatTime(key)), mCount(0) {}
  142. LLStatTime mStat;
  143. U32 mCount;
  144. };
  145. typedef std::map<std::string, StatEntry*> stat_map_t;
  146. // Use this constructor for pre-defined LLStatTime objects
  147. LLPerfBlock(LLStatTime* stat);
  148. // Use this constructor for normal, optional LLPerfBlock time slices
  149. LLPerfBlock( const char* key );
  150. // Use this constructor for dynamically created LLPerfBlock time slices
  151. // that are only enabled by specific control flags
  152. LLPerfBlock( const char* key1, const char* key2, S32 flags = LLSTATS_BASIC_STATS );
  153. ~LLPerfBlock();
  154. enum
  155. { // Stats bitfield flags
  156. LLSTATS_NO_OPTIONAL_STATS = 0x00, // No optional stats gathering, just pre-defined LLStatTime objects
  157. LLSTATS_BASIC_STATS = 0x01, // Gather basic optional runtime stats
  158. LLSTATS_SCRIPT_FUNCTIONS = 0x02, // Include LSL function calls
  159. };
  160. static void setStatsFlags( S32 flags ) { sStatsFlags = flags; };
  161. static S32 getStatsFlags() { return sStatsFlags; };
  162. static void clearDynamicStats(); // Reset maps to clear out dynamic objects
  163. static void addStatsToLLSDandReset( LLSD & stats, // Get current information and clear time bin
  164. LLStatAccum::TimeScale scale );
  165. private:
  166. // Initialize dynamically created LLStatTime objects
  167. void initDynamicStat(const std::string& key);
  168. std::string mLastPath; // Save sCurrentStatPath when this is called
  169. LLStatTime * mPredefinedStat; // LLStatTime object to get data
  170. StatEntry * mDynamicStat; // StatEntryobject to get data
  171. static S32 sStatsFlags; // Control what is being recorded
  172. static stat_map_t sStatMap; // Map full path string to LLStatTime objects
  173. static std::string sCurrentStatPath; // Something like "frame/physics/physics step"
  174. };
  175. // ----------------------------------------------------------------------------
  176. class LL_COMMON_API LLPerfStats
  177. {
  178. public:
  179. LLPerfStats(const std::string& process_name = "unknown", S32 process_pid = 0);
  180. virtual ~LLPerfStats();
  181. virtual void init(); // Reset and start all stat timers
  182. virtual void updatePerFrameStats();
  183. // Override these function to add process-specific information to the performance log header and per-frame logging.
  184. virtual void addProcessHeaderInfo(LLSD& info) { /* not implemented */ }
  185. virtual void addProcessFrameInfo(LLSD& info, LLStatAccum::TimeScale scale) { /* not implemented */ }
  186. // High-resolution frame stats
  187. BOOL frameStatsIsRunning() { return (mReportPerformanceStatEnd > 0.); };
  188. F32 getReportPerformanceInterval() const { return mReportPerformanceStatInterval; };
  189. void setReportPerformanceInterval( F32 interval ) { mReportPerformanceStatInterval = interval; };
  190. void setReportPerformanceDuration( F32 seconds, S32 flags = LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS );
  191. void setProcessName(const std::string& process_name) { mProcessName = process_name; }
  192. void setProcessPID(S32 process_pid) { mProcessPID = process_pid; }
  193. protected:
  194. void openPerfStatsFile(); // Open file for high resolution metrics logging
  195. void dumpIntervalPerformanceStats();
  196. llofstream mFrameStatsFile; // File for per-frame stats
  197. BOOL mFrameStatsFileFailure; // Flag to prevent repeat opening attempts
  198. BOOL mSkipFirstFrameStats; // Flag to skip one (partial) frame report
  199. std::string mProcessName;
  200. S32 mProcessPID;
  201. private:
  202. F32 mReportPerformanceStatInterval; // Seconds between performance stats
  203. F64 mReportPerformanceStatEnd; // End time (seconds) for performance stats
  204. };
  205. // ----------------------------------------------------------------------------
  206. class LL_COMMON_API LLStat
  207. {
  208. private:
  209. typedef std::multimap<std::string, LLStat*> stat_map_t;
  210. static stat_map_t sStatList;
  211. void init();
  212. public:
  213. LLStat(U32 num_bins = 32, BOOL use_frame_timer = FALSE);
  214. LLStat(std::string name, U32 num_bins = 32, BOOL use_frame_timer = FALSE);
  215. ~LLStat();
  216. void reset();
  217. void start(); // Start the timer for the current "frame", otherwise uses the time tracked from
  218. // the last addValue
  219. void addValue(const F32 value = 1.f); // Adds the current value being tracked, and tracks the DT.
  220. void addValue(const S32 value) { addValue((F32)value); }
  221. void addValue(const U32 value) { addValue((F32)value); }
  222. void setBeginTime(const F64 time);
  223. void addValueTime(const F64 time, const F32 value = 1.f);
  224. S32 getCurBin() const;
  225. S32 getNextBin() const;
  226. F32 getCurrent() const;
  227. F32 getCurrentPerSec() const;
  228. F64 getCurrentBeginTime() const;
  229. F64 getCurrentTime() const;
  230. F32 getCurrentDuration() const;
  231. F32 getPrev(S32 age) const; // Age is how many "addValues" previously - zero is current
  232. F32 getPrevPerSec(S32 age) const; // Age is how many "addValues" previously - zero is current
  233. F64 getPrevBeginTime(S32 age) const;
  234. F64 getPrevTime(S32 age) const;
  235. F32 getBin(S32 bin) const;
  236. F32 getBinPerSec(S32 bin) const;
  237. F64 getBinBeginTime(S32 bin) const;
  238. F64 getBinTime(S32 bin) const;
  239. F32 getMax() const;
  240. F32 getMaxPerSec() const;
  241. F32 getMean() const;
  242. F32 getMeanPerSec() const;
  243. F32 getMeanDuration() const;
  244. F32 getMin() const;
  245. F32 getMinPerSec() const;
  246. F32 getMinDuration() const;
  247. F32 getSum() const;
  248. F32 getSumDuration() const;
  249. U32 getNumValues() const;
  250. S32 getNumBins() const;
  251. F64 getLastTime() const;
  252. private:
  253. BOOL mUseFrameTimer;
  254. U32 mNumValues;
  255. U32 mNumBins;
  256. F32 mLastValue;
  257. F64 mLastTime;
  258. F32 *mBins;
  259. F64 *mBeginTime;
  260. F64 *mTime;
  261. F32 *mDT;
  262. S32 mCurBin;
  263. S32 mNextBin;
  264. std::string mName;
  265. static LLTimer sTimer;
  266. static LLFrameTimer sFrameTimer;
  267. public:
  268. static LLStat* getStat(const std::string& name)
  269. {
  270. // return the first stat that matches 'name'
  271. stat_map_t::iterator iter = sStatList.find(name);
  272. if (iter != sStatList.end())
  273. return iter->second;
  274. else
  275. return NULL;
  276. }
  277. };
  278. #endif // LL_STAT_