Alexandre Lision | 8af73cb | 2013-12-10 14:11:20 -0500 | [diff] [blame] | 1 | //------------------------------------------------------------------------------
|
| 2 | // File: Measure.h
|
| 3 | //
|
| 4 | // Desc: DirectShow base classes.
|
| 5 | //
|
| 6 | // Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
|
| 7 | //------------------------------------------------------------------------------
|
| 8 |
|
| 9 |
|
| 10 | /*
|
| 11 | The idea is to pepper the source code with interesting measurements and
|
| 12 | have the last few thousand of these recorded in a circular buffer that
|
| 13 | can be post-processed to give interesting numbers.
|
| 14 |
|
| 15 | WHAT THE LOG LOOKS LIKE:
|
| 16 |
|
| 17 | Time (sec) Type Delta Incident_Name
|
| 18 | 0.055,41 NOTE -. Incident Nine - Another note
|
| 19 | 0.055,42 NOTE 0.000,01 Incident Nine - Another note
|
| 20 | 0.055,44 NOTE 0.000,02 Incident Nine - Another note
|
| 21 | 0.055,45 STOP -. Incident Eight - Also random
|
| 22 | 0.055,47 START -. Incident Seven - Random
|
| 23 | 0.055,49 NOTE 0.000,05 Incident Nine - Another note
|
| 24 | ------- <etc. there is a lot of this> ----------------
|
| 25 | 0.125,60 STOP 0.000,03 Msr_Stop
|
| 26 | 0.125,62 START -. Msr_Start
|
| 27 | 0.125,63 START -. Incident Two - Start/Stop
|
| 28 | 0.125,65 STOP 0.000,03 Msr_Start
|
| 29 | 0.125,66 START -. Msr_Stop
|
| 30 | 0.125,68 STOP 0.000,05 Incident Two - Start/Stop
|
| 31 | 0.125,70 STOP 0.000,04 Msr_Stop
|
| 32 | 0.125,72 START -. Msr_Start
|
| 33 | 0.125,73 START -. Incident Two - Start/Stop
|
| 34 | 0.125,75 STOP 0.000,03 Msr_Start
|
| 35 | 0.125,77 START -. Msr_Stop
|
| 36 | 0.125,78 STOP 0.000,05 Incident Two - Start/Stop
|
| 37 | 0.125,80 STOP 0.000,03 Msr_Stop
|
| 38 | 0.125,81 NOTE -. Incident Three - single Note
|
| 39 | 0.125,83 START -. Incident Four - Start, no stop
|
| 40 | 0.125,85 START -. Incident Five - Single Start/Stop
|
| 41 | 0.125,87 STOP 0.000,02 Incident Five - Single Start/Stop
|
| 42 |
|
| 43 | Number Average StdDev Smallest Largest Incident_Name
|
| 44 | 10 0.000,58 0.000,10 0.000,55 0.000,85 Incident One - Note
|
| 45 | 50 0.000,05 0.000,00 0.000,05 0.000,05 Incident Two - Start/Stop
|
| 46 | 1 -. -. -. -. Incident Three - single Note
|
| 47 | 0 -. -. -. -. Incident Four - Start, no stop
|
| 48 | 1 0.000,02 -. 0.000,02 0.000,02 Incident Five - Single Start/Stop
|
| 49 | 0 -. -. -. -. Incident Six - zero occurrences
|
| 50 | 100 0.000,25 0.000,12 0.000,02 0.000,62 Incident Seven - Random
|
| 51 | 100 0.000,79 0.000,48 0.000,02 0.001,92 Incident Eight - Also random
|
| 52 | 5895 0.000,01 0.000,01 0.000,01 0.000,56 Incident Nine - Another note
|
| 53 | 10 0.000,03 0.000,00 0.000,03 0.000,04 Msr_Note
|
| 54 | 50 0.000,03 0.000,00 0.000,03 0.000,04 Msr_Start
|
| 55 | 50 0.000,04 0.000,03 0.000,03 0.000,31 Msr_Stop
|
| 56 |
|
| 57 | WHAT IT MEANS:
|
| 58 | The log shows what happened and when. Each line shows the time at which
|
| 59 | something happened (see WHAT YOU CODE below) what it was that happened
|
| 60 | and (if approporate) the time since the corresponding previous event
|
| 61 | (that's the delta column).
|
| 62 |
|
| 63 | The statistics show how many times each event occurred, what the average
|
| 64 | delta time was, also the standard deviation, largest and smalles delta.
|
| 65 |
|
| 66 | WHAT YOU CODE:
|
| 67 |
|
| 68 | Before anything else executes: - register your ids
|
| 69 |
|
| 70 | int id1 = Msr_Register("Incident One - Note");
|
| 71 | int id2 = Msr_Register("Incident Two - Start/Stop");
|
| 72 | int id3 = Msr_Register("Incident Three - single Note");
|
| 73 | etc.
|
| 74 |
|
| 75 | At interesting moments:
|
| 76 |
|
| 77 | // To measure a repetitive event - e.g. end of bitblt to screen
|
| 78 | Msr_Note(Id9); // e.g. "video frame hiting the screen NOW!"
|
| 79 |
|
| 80 | or
|
| 81 |
|
| 82 | // To measure an elapsed time e.g. time taken to decode an MPEG B-frame
|
| 83 | Msr_Start(Id2); // e.g. "Starting to decode MPEG B-frame"
|
| 84 | . . .
|
| 85 | MsrStop(Id2); // "Finished MPEG decode"
|
| 86 |
|
| 87 | At the end:
|
| 88 |
|
| 89 | HANDLE hFile;
|
| 90 | hFile = CreateFile("Perf.log", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
|
| 91 | Msr_Dump(hFile); // This writes the log out to the file
|
| 92 | CloseHandle(hFile);
|
| 93 |
|
| 94 | or
|
| 95 |
|
| 96 | Msr_Dump(NULL); // This writes it to DbgLog((LOG_TRACE,0, ... ));
|
| 97 | // but if you are writing it out to the debugger
|
| 98 | // then the times are probably all garbage because
|
| 99 | // the debugger can make things run awfully slow.
|
| 100 |
|
| 101 | A given id should be used either for start / stop or Note calls. If Notes
|
| 102 | are mixed in with Starts and Stops their statistics will be gibberish.
|
| 103 |
|
| 104 | If you code the calls in upper case i.e. MSR_START(idMunge); then you get
|
| 105 | macros which will turn into nothing unless PERF is defined.
|
| 106 |
|
| 107 | You can reset the statistical counts for a given id by calling Reset(Id).
|
| 108 | They are reset by default at the start.
|
| 109 | It logs Reset as a special incident, so you can see it in the log.
|
| 110 |
|
| 111 | The log is a circular buffer in storage (to try to minimise disk I/O).
|
| 112 | It overwrites the oldest entries once full. The statistics include ALL
|
| 113 | incidents since the last Reset, whether still visible in the log or not.
|
| 114 | */
|
| 115 |
|
| 116 | #ifndef __MEASURE__
|
| 117 | #define __MEASURE__
|
| 118 |
|
| 119 | #ifdef PERF
|
| 120 | #define MSR_INIT() Msr_Init()
|
| 121 | #define MSR_TERMINATE() Msr_Terminate()
|
| 122 | #define MSR_REGISTER(a) Msr_Register(a)
|
| 123 | #define MSR_RESET(a) Msr_Reset(a)
|
| 124 | #define MSR_CONTROL(a) Msr_Control(a)
|
| 125 | #define MSR_START(a) Msr_Start(a)
|
| 126 | #define MSR_STOP(a) Msr_Stop(a)
|
| 127 | #define MSR_NOTE(a) Msr_Note(a)
|
| 128 | #define MSR_INTEGER(a,b) Msr_Integer(a,b)
|
| 129 | #define MSR_DUMP(a) Msr_Dump(a)
|
| 130 | #define MSR_DUMPSTATS(a) Msr_DumpStats(a)
|
| 131 | #else
|
| 132 | #define MSR_INIT() ((void)0)
|
| 133 | #define MSR_TERMINATE() ((void)0)
|
| 134 | #define MSR_REGISTER(a) 0
|
| 135 | #define MSR_RESET(a) ((void)0)
|
| 136 | #define MSR_CONTROL(a) ((void)0)
|
| 137 | #define MSR_START(a) ((void)0)
|
| 138 | #define MSR_STOP(a) ((void)0)
|
| 139 | #define MSR_NOTE(a) ((void)0)
|
| 140 | #define MSR_INTEGER(a,b) ((void)0)
|
| 141 | #define MSR_DUMP(a) ((void)0)
|
| 142 | #define MSR_DUMPSTATS(a) ((void)0)
|
| 143 | #endif
|
| 144 |
|
| 145 | #ifdef __cplusplus
|
| 146 | extern "C" {
|
| 147 | #endif
|
| 148 |
|
| 149 | // This must be called first - (called by the DllEntry)
|
| 150 |
|
| 151 | void WINAPI Msr_Init(void);
|
| 152 |
|
| 153 |
|
| 154 | // Call this last to clean up (or just let it fall off the end - who cares?)
|
| 155 |
|
| 156 | void WINAPI Msr_Terminate(void);
|
| 157 |
|
| 158 |
|
| 159 | // Call this to get an Id for an "incident" that you can pass to Start, Stop or Note
|
| 160 | // everything that's logged is called an "incident".
|
| 161 |
|
| 162 | int WINAPI Msr_Register(__in LPTSTR Incident);
|
| 163 |
|
| 164 |
|
| 165 | // Reset the statistical counts for an incident
|
| 166 |
|
| 167 | void WINAPI Msr_Reset(int Id);
|
| 168 |
|
| 169 |
|
| 170 | // Reset all the counts for all incidents
|
| 171 | #define MSR_RESET_ALL 0
|
| 172 | #define MSR_PAUSE 1
|
| 173 | #define MSR_RUN 2
|
| 174 |
|
| 175 | void WINAPI Msr_Control(int iAction);
|
| 176 |
|
| 177 |
|
| 178 | // log the start of an operation
|
| 179 |
|
| 180 | void WINAPI Msr_Start(int Id);
|
| 181 |
|
| 182 |
|
| 183 | // log the end of an operation
|
| 184 |
|
| 185 | void WINAPI Msr_Stop(int Id);
|
| 186 |
|
| 187 |
|
| 188 | // log a one-off or repetitive operation
|
| 189 |
|
| 190 | void WINAPI Msr_Note(int Id);
|
| 191 |
|
| 192 |
|
| 193 | // log an integer (on which we can see statistics later)
|
| 194 | void WINAPI Msr_Integer(int Id, int n);
|
| 195 |
|
| 196 |
|
| 197 | // print out all the vaialable log (it may have wrapped) and then the statistics.
|
| 198 | // When the log wraps you lose log but the statistics are still complete.
|
| 199 | // hFIle==NULL => use DbgLog
|
| 200 | // otherwise hFile must have come from CreateFile or OpenFile.
|
| 201 |
|
| 202 | void WINAPI Msr_Dump(HANDLE hFile);
|
| 203 |
|
| 204 |
|
| 205 | // just dump the statistics - never mind the log
|
| 206 |
|
| 207 | void WINAPI Msr_DumpStats(HANDLE hFile);
|
| 208 |
|
| 209 | // Type definitions in case you want to declare a pointer to the dump functions
|
| 210 | // (makes it a trifle easier to do dynamic linking
|
| 211 | // i.e. LoadModule, GetProcAddress and call that)
|
| 212 |
|
| 213 | // Typedefs so can declare MSR_DUMPPROC *MsrDumpStats; or whatever
|
| 214 | typedef void WINAPI MSR_DUMPPROC(HANDLE hFile);
|
| 215 | typedef void WINAPI MSR_CONTROLPROC(int iAction);
|
| 216 |
|
| 217 |
|
| 218 | #ifdef __cplusplus
|
| 219 | }
|
| 220 | #endif
|
| 221 |
|
| 222 | #endif // __MEASURE__
|