llstat.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:11k
源码类别:

游戏引擎

开发平台:

C++ Builder

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