hkMonitorStreamAnalyzer.h
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:18k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* 
  2.  * 
  3.  * Confidential Information of Telekinesys Research Limited (t/a Havok). Not for disclosure or distribution without Havok's
  4.  * prior written consent. This software contains code, techniques and know-how which is confidential and proprietary to Havok.
  5.  * Level 2 and Level 3 source code contains trade secrets of Havok. Havok Software (C) Copyright 1999-2009 Telekinesys Research Limited t/a Havok. All Rights Reserved. Use of this software is subject to the terms of an end user license agreement.
  6.  * 
  7.  */
  8. #ifndef HKBASE_MONITOR_STREAM_ANALYZER_H
  9. #define HKBASE_MONITOR_STREAM_ANALYZER_H
  10. #include <Common/Base/Monitor/hkMonitorStream.h>
  11. #include <Common/Base/Container/PointerMap/hkPointerMap.h>
  12. #include <Common/Base/Container/Array/hkObjectArray.h>
  13. #include <Common/Base/System/Io/OStream/hkOStream.h>
  14. #include <Common/Base/Types/Color/hkColor.h>
  15. extern const hkClass hkMonitorStreamStringMapClass;
  16. struct hkMonitorStreamStringMap
  17. {
  18. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR(HK_MEMORY_CLASS_MONITOR, hkMonitorStreamStringMap);
  19. HK_DECLARE_REFLECTION();
  20. struct StringMap
  21. {
  22. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_BASE_CLASS, hkMonitorStreamStringMap::StringMap );
  23. HK_DECLARE_REFLECTION();
  24. HK_ALIGN(hkUint64 m_id,8); // no ulong in serialization yet, and void* will be zero 
  25. const char* m_string;
  26. };
  27. hkArray<struct StringMap> m_map;
  28. };
  29. /// Information about how to read the data from the monitors captured over a
  30. /// given frame. You need to fill this structure in per frame captured.
  31. /// The timing monitors are setup to capture 2 floats per call. However,
  32. /// there are 4 "slots" in the corresponding monitor capture structure here.
  33. /// This allows you for example to alternate between i-cache and d-cache misses
  34. /// per frame and send them to different slots in the capture.
  35. extern const hkClass hkMonitorStreamFrameInfoClass;
  36. struct hkMonitorStreamFrameInfo
  37. {
  38. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_MONITOR, hkMonitorStreamFrameInfo ); 
  39. HK_DECLARE_REFLECTION();
  40. // To keep the Visual Debugger backward compatible as much as possible, try not to 
  41. // add any members to this struct. If you do, add them at the end (in the second public section)
  42. // (to make the version-ing trivial) as the VDB client does not have version-ing, and serializes this struct 
  43. // directly.  
  44. /// The heading for the frame (which will be printed out in the detailed timings file)
  45. /// Typically you should not forget to record what timers are being used for, and what units you
  46. /// are measuring times in (e.g. usec).
  47. const char* m_heading;
  48. /// The slot in our monitor capture structure, where the timer 0 should be stored
  49. /// If this is set to -1, timer 0 will not get stored. By default this is 0.
  50. hkInt32 m_indexOfTimer0;
  51. /// The slot in our monitor capture structure, where the timer 1 should be stored
  52. /// If this is set to -1, timer 1 will not get stored. By default this is 1.
  53. hkInt32 m_indexOfTimer1;
  54. /// The index of the absolute time. This should be 0 if timer O is used to
  55. /// store the absolute time, 1 if timer 1 is used to store the absolute time
  56. /// and -1 if neither timer 0 or timer 1 are used to store absolute time.
  57. /// This value is used to draw multiple timer threads to an image.
  58. /// By default this is ABSOLUTE_TIME_TIMER_0.
  59. enum AbsoluteTimeCounter
  60. {
  61. ABSOLUTE_TIME_TIMER_0 = 0,
  62. ABSOLUTE_TIME_TIMER_1 = 1,
  63. ABSOLUTE_TIME_NOT_TIMED = -1
  64. };
  65. /// Which timer if either is used to measure absolute time
  66. hkEnum<AbsoluteTimeCounter,hkUint32> m_absoluteTimeCounter;
  67. /// This value is used to multiply the raw data collected by the monitors and written into slot 0 of the
  68. /// monitor capture structure.  The value should be set depending on what information the monitors are 
  69. /// collecting for this slot. (e.g. timings, cache misses). For example, if you wish to display timings
  70. /// in microseconds you would set this value to (1 / number of clock cycles per microsecond).  Using hkBase
  71. /// this would be 1e6f / float(hkStopwatch::getTicksPerSecond());
  72. /// By default this is 1.f
  73. hkReal m_timerFactor0;
  74. /// This value is used to multiply the raw data collected by the monitors and written into slot 1 of the
  75. /// monitor capture structure.  See comments for m_timerFactor0 for more info. 
  76. /// By default this is 1.f
  77. hkReal m_timerFactor1;
  78. public:
  79. /// The thread that this frame data came from.  This must be between 0 and the number of
  80. /// threads passed into the analyzer on construction.
  81. /// Only need to set this if you are calling captureFrameDetails().
  82. int m_threadId;
  83. /// Set automatically when you call captureFrameDetails. There is no need to initialize this value.
  84. int m_frameStreamStart;
  85. /// Set automatically when you call captureFrameDetails. There is no need to initialize this value.
  86. int m_frameStreamEnd;
  87. /// Constructor. Initializes values to defaults as documented.
  88. hkMonitorStreamFrameInfo();
  89. };
  90. /// The input structure for the drawThreadsToTga function. Each thread is drawn as
  91. /// a colored bar, with different colors indicating different timers.
  92. extern const hkClass hkMonitorStreamColorTableClass;
  93. struct hkMonitorStreamColorTable : public hkReferencedObject
  94. {
  95. //+vtable(true)
  96. public:
  97. HK_DECLARE_CLASS_ALLOCATOR( HK_MEMORY_CLASS_MONITOR );
  98. HK_DECLARE_REFLECTION();
  99. hkMonitorStreamColorTable() 
  100. m_defaultColor = 0xFFFFFFFF; 
  101. }
  102. /// A mapping of timer names to colors
  103. struct ColorPair
  104. {
  105. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_MONITOR, hkMonitorStreamColorTable::ColorPair );
  106. HK_DECLARE_REFLECTION();
  107. const char* m_colorName;
  108. hkEnum<hkColor::ExtendedColors, hkUint32> m_color;
  109. ColorPair( const char* name, hkColor::ExtendedColors color )
  110. : m_colorName( name), 
  111. m_color( color ){}
  112. };
  113. hkArray< struct ColorPair > m_colorPairs;
  114. hkUint32 m_defaultColor;
  115. hkUint32 findColor( const char* color );
  116. void addColor( const char* name, hkColor::ExtendedColors color );
  117. void setupDefaultColorTable();
  118. hkMonitorStreamColorTable( class hkFinishLoadedObjectFlag flag ) : hkReferencedObject(flag), m_colorPairs(flag) {}
  119. };
  120. /// Allows you to capture several frames (generated by hkMonitorStream)
  121. /// and convert the data stream into a stream that can be moved across the network.
  122. /// Also this class allows you to pretty print the results to a file.
  123. class hkMonitorStreamAnalyzer
  124. {
  125. public:
  126. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR(HK_MEMORY_CLASS_MONITOR, hkMonitorStreamAnalyzer);
  127. ///////////////////////////////////////////////////////////////////////
  128. //
  129. // Constructor, monitor capture, and reset
  130. //
  131. ///////////////////////////////////////////////////////////////////////
  132. /// Create an analyzer given a maximum memory size. This will allocate a block of data
  133. /// with this size, and use it to copy monitor information when captureFrameDetails is called.
  134. hkMonitorStreamAnalyzer( int maxMemorySize, int numThreads = 1, int numSpus = 0 );
  135. /// This function must be called every frame. It copies the data between monitorStreamBegin and
  136. /// monitorStreamEnd, and stores the frame info structure.
  137. hkBool captureFrameDetails( const char* monitorStreamBegin, const char* monitorStreamEnd, hkMonitorStreamFrameInfo& info );
  138. /// This allows you to change the number of threads the analyzer captures
  139. /// This resets the analyzer. It clears all the arrays, but does not deallocate any data.
  140. void resetNumThreads( int numThreads = 1, int numSpus = 0 );
  141. /// This resets the analyzer. It clears all the arrays, but does not deallocate any data.
  142. void reset();
  143. /// Get the start of the data stream.
  144. /// If the steam is empty, HK_NULL will be returned.
  145. char* getStreamBegin();
  146. ///////////////////////////////////////////////////////////////////////
  147. //
  148. // Utilities to write .txt statistics files
  149. //
  150. ///////////////////////////////////////////////////////////////////////
  151. enum
  152. {
  153. REPORT_ALL = 0xFF,
  154. REPORT_SUMMARIES = 0x07,
  155. REPORT_TOTAL = 0x01,
  156. REPORT_PERFRAME_TIME = 0x02,
  157. REPORT_PERFRAME_SUMMARY = 0x04,
  158. REPORT_PERFRAME_DETAIL = 0x08
  159. };
  160. /// Create a user readable statistics file of the raw data.
  161. void writeStatistics( hkOstream& outstream, int reportLevel = REPORT_ALL );
  162. ///////////////////////////////////////////////////////////////////////
  163. //
  164. // Utilities to draw statistics to an image
  165. //
  166. ///////////////////////////////////////////////////////////////////////
  167. struct ThreadDrawInput
  168. {
  169. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_MONITOR, hkMonitorStreamAnalyzer::ThreadDrawInput );
  170. /// The frame to start drawing from (1 by default)
  171. hkInt32 m_frameStart;
  172. /// The number of frames to draw (1 by default)
  173. hkInt32 m_numFrames;
  174. /// Layout info
  175. hkInt32 m_heightPerThread;
  176. /// Layout info
  177. hkInt32 m_gapBetweenThreads;
  178. hkInt32 m_gapBetweenFrames;
  179. /// Number of samples to take per frame
  180. hkInt32 m_outputPixelWidth;  
  181. /// Set this to > 0 if you want to limit the frame duration
  182. hkReal m_limitFrameTime;
  183. hkReal m_limitStartTime;
  184. hkBool m_warnAboutMissingTimers;
  185. static int HK_CALL computePerThreadHeightToFit( int textureHeight, int numFrames, int numThreads, int frameGap, int threadGap );
  186. /// A mapping of timer names to colors
  187. struct hkMonitorStreamColorTable* m_colorTable;
  188. };
  189. /// Draw the current thread data as held by this analyzer to a .tga file
  190. void drawThreadsToTga( const ThreadDrawInput& input, hkOstream& outStream );
  191. ///////////////////////////////////////////////////////////////////////
  192. //
  193. // Utilities to print timers to a runtime display
  194. //
  195. ///////////////////////////////////////////////////////////////////////
  196. struct Node; 
  197. /// You can use this function in conjunction with mergeTreesForCombinedThreadSummary, navigateMonitors and printMonitorsToRuntimeDisplay 
  198. /// to display user navigatable timers on screen. You need to be able to output text to the screen, and capture
  199. /// cursor key input to do this. 
  200. /// This call will create a tree of nodes given a monitor stream start and end. It returns the root node of the tree.
  201. /// For multithreaded applications, you will have a monitor stream per thread. You call this on each monitor stream,
  202. /// and merge the results together using mergeTreesForRuntimeDisplay. You can then use navigateMonitors and 
  203. /// printMonitorsToRuntimeDisplay to view the combined trees.
  204. static Node* HK_CALL makeStatisticsTreeForSingleFrame( const char* frameStart, const char* frameEnd, const hkMonitorStreamFrameInfo& info, const char* rootNodeName = "/", hkBool reuseNodesIfPossible = true );
  205. /// Given two trees, this function takes all the nodes in the subTree and merges them into the main tree. The sourceTimerId
  206. /// describes which slot in the subTree nodes the time is stored. This corresponds with your monitor setup, but is usually 0.
  207. /// The destTimerId describes which slot in the main tree nodes you wish to write. There are 4 slots, so this value must be
  208. /// between 0 and 3. If a node exists in the subTree but not in mainTree it is created. The smoothingFactor describes
  209. /// how the value is smoothed as it changes over time. Values closer to 1 smooth the timers more. 0 is unsmoothed.
  210. static void HK_CALL mergeTreesForCombinedThreadSummary( Node* mainTree, Node* subTree, int destTimerId, int sourceTimerId = 0, hkReal smoothingFactor = .93f );
  211. /// Set these values from your input device. This is used as an input to navigateMonitors
  212. struct CursorKeys
  213. {
  214. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_MONITOR, hkMonitorStreamAnalyzer::CursorKeys );
  215. /// up
  216. hkBool m_upPressed;
  217. /// down
  218. hkBool m_downPressed;
  219. /// left
  220. hkBool m_leftPressed;
  221. /// right
  222. hkBool m_rightPressed;
  223. };
  224. /// This function returns the new active node, given the current active node and the cursor keys.
  225. static Node* HK_CALL navigateMonitors( const CursorKeys& keys, Node* activeNodeIn );
  226. /// The options structure for showCombinedThreadSummaryForSingleFrame
  227. struct CombinedThreadSummaryOptions
  228. {
  229. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_MONITOR, hkMonitorStreamAnalyzer::CombinedThreadSummaryOptions );
  230. /// Spacing info
  231. int m_indentationToFirstTimerValue;
  232. /// Spacing info
  233. int m_timerColumnWidth;
  234. /// Spacing info
  235. int m_tabSpacingForTimerNames;
  236. /// Spacing info
  237. int m_tabSpacingForTimerValues;
  238. /// If set, only nodes with user flags set will be displayed. User flags are set by the navigateMonitors function
  239. bool m_displayPartialTree;
  240. /// The current selected node - only set if m_displayPartialTree is true
  241. Node* m_activeNode; 
  242. /// Only set if m_displayPartialTree is true
  243. char m_rightArrowChar;
  244. /// Only set if m_displayPartialTree is true
  245. char m_downArrowChar; 
  246. };
  247. /// This function prints the monitor tree to an hkOstream. You can create an hkOstream from an array of char,
  248. /// then print this array to the screen, or to file. The rootNode is the root of the tree, and the active node is the
  249. /// current selected node, returned by navigateMonitors. The numThreads is the number of fields (from 1 to 4)
  250. /// to print. The unexpanded and expanded variables allow you to insert your own graphics for these markers.
  251. static void HK_CALL showCombinedThreadSummaryForSingleFrame( Node* node, int numThreads, int numSpus, hkOstream& os, CombinedThreadSummaryOptions& options );
  252. public:
  253. //
  254. // Static internal utility methods and data used for the above functions
  255. //
  256. // 2 ppu and 6 spu threads, or 2 QuadCores.
  257. // The higher this number the more mem is used during timer analysis 
  258. enum { NUM_VALUES = 8};
  259. /// Data to store the parsed results of a capture
  260. struct Node
  261. {
  262. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_MONITOR, Node );
  263. enum NodeType
  264. {
  265. NODE_TYPE_TIMER,
  266. NODE_TYPE_DIRECTORY,
  267. NODE_TYPE_SINGLE,
  268. };
  269. hkReal m_value[NUM_VALUES];
  270. hkUint16 m_count[NUM_VALUES];
  271. hkArray<struct Node*> m_children;
  272. double m_absoluteStartTime; // this needs double precission
  273. Node* m_parent;
  274. const char* m_name;
  275. hkUint32 m_userFlags;
  276. hkEnum<NodeType,hkUint32> m_type;
  277. Node(Node* parent, const char* name, NodeType type );
  278. Node() {}
  279. void setTimers( const hkMonitorStreamFrameInfo& frameInfo, const hkMonitorStream::TimerCommand& start, const hkMonitorStream::TimerCommand& end);
  280. ~Node();
  281. };
  282. static int HK_CALL findMaxTimerNameIndent( hkMonitorStreamAnalyzer::Node* node, int recursionDepth, int spacing, bool displayPartialTree );
  283. static void HK_CALL showCombinedThreadSummaryRec( hkOstream& os, hkMonitorStreamAnalyzer::Node* node, int recursionDepth, int numThreads, int numSpus, const CombinedThreadSummaryOptions& options );
  284. Node* HK_CALL makeStatisticsTreeForMultipleFrames( int threadId, hkBool reuseNodesIfPossible = false);
  285. void checkAllThreadsCapturedSameNumFrames() const;
  286. static void HK_CALL writeStatisticsDetails( hkOstream& outstream, hkArray<Node*>& nodes, int numThreads, int numSpus, int reportLevel, const char* nodeIdForFrameOverview = "", bool showMultithreadedSummary = false );
  287. static void HK_CALL extractStringMap( const char* frameStart, const char* frameEnd, hkPointerMap<const void*, const char*>& map );
  288. static void HK_CALL applyStringMap( const char* frameStart, const char* frameEnd, const hkPointerMap<const void*, const char*>& map, hkBool endianSwap );
  289. struct SampleInfo
  290. {
  291. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_MONITOR, hkMonitorStreamAnalyzer::SampleInfo );
  292. hkReal m_maxSampleTime;
  293. };
  294. /// called by drawThreadsToTga (and the VDB). Call hkDeallocate on the data when you are done. Always has 4 bytes per pixel.
  295. static void HK_CALL writeStatisticsDetailsToTexture( hkArray<Node*>& nodes, const ThreadDrawInput& input, hkObjectArray< hkArray< hkMonitorStreamFrameInfo > >& frameInfos, int*& textureData, int& height, SampleInfo* sampleInfo = HK_NULL );
  296. /// called by drawThreadsToTga (and the VDB). Calls the above and writes it in a simple TARGA format.
  297. static void HK_CALL writeStatisticsDetailsToTga( hkArray<Node*>& nodes, const ThreadDrawInput& input, hkObjectArray< hkArray< hkMonitorStreamFrameInfo > >& frameInfos, hkOstream& outStream, SampleInfo* sampleInfo = HK_NULL );
  298. static Node* HK_CALL reverseLookupNodeAtTgaSample( int x, int y, hkArray<Node*>& nodes, const ThreadDrawInput& input, hkObjectArray< hkArray< hkMonitorStreamFrameInfo > >& frameInfos );
  299. static void HK_CALL getTimerLimits( hkArray<Node*>& nodeList, const ThreadDrawInput& input, hkObjectArray< hkArray< hkMonitorStreamFrameInfo > >& frameInfos, hkReal& maxFrameTime, hkArray<hkReal>& startTimes);
  300. protected:
  301. //
  302. // Data for multiple frames
  303. //
  304. hkObjectArray< hkArray< hkMonitorStreamFrameInfo > > m_frameInfos;
  305. hkArray<char> m_data;
  306. int m_numThreads;
  307. int m_numSpus;
  308. public:
  309. static hkReal g_lastFrameTime;
  310. const char* m_nodeIdForFrameOverview;
  311. };
  312. #endif // HKBASE_MONITOR_STREAM_ANALYZER_H
  313. /*
  314. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  315. * Confidential Information of Havok.  (C) Copyright 1999-2009
  316. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  317. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  318. * rights, and intellectual property rights in the Havok software remain in
  319. * Havok and/or its suppliers.
  320. * Use of this software for evaluation purposes is subject to and indicates
  321. * acceptance of the End User licence Agreement for this product. A copy of
  322. * the license is included with this software and is also available at www.havok.com/tryhavok.
  323. */