00001 /* 00002 *************************************************************************************************** 00003 *************************************************************************************************** 00004 *** 00005 *** File Name: WFProfiler.h 00006 *** Description: Header file to define the WFProfiler macros and function declarations. 00007 *** Notes: These macros are specific to the Intel Pentium processors. Also, the code 00008 *** is specific to the MS Visual C++ compiler due to the __int64 declarations. 00009 *** 00010 *** Unfortunately, these macros are useless to determine small operations such as 00011 *** single shifts, single adds etc. For some reason, they reflect as taking -2 00012 *** clock cycles to complete. Is this due to caching? Multi-processing? Who knows. 00013 *** When testing from Start()-Stop() with no instructions in between, I repeatedly 00014 *** recieve a 0-cycle count as expected. Intel even states that the RDTSC instruction 00015 *** is not perfect - especially when combined with CPUID. Check out the web-site: 00016 *** 00017 *** http://developer.intel.com/ for more information. (Search for RDTSC)... 00018 *** 00019 *** 00020 *** Example: 00021 *** 00022 *** #include <windows.h> 00023 *** #include "..\Header Files\WFProfiler.h" 00024 *** 00025 *** 00026 *** int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) 00027 *** { 00028 *** 00029 *** WF_PROFILER profile; 00030 *** int y=0; 00031 *** 00032 *** Reset(profile); 00033 *** Start(profile); 00034 *** 00035 *** // This section is being timed... 00036 *** for (int x=0; x<1000; x++) 00037 *** { 00038 *** y = rand() % 32; 00039 *** } 00040 *** 00041 *** Stop(profile); 00042 *** 00043 *** 00044 *** // **************************************************************** 00045 *** // **************************************************************** 00046 *** // How long was the average pass through the FOR loop...? 00047 *** // Exit Code tells ya (Mine shows 18-cycles - P3-700Mhz)... 00048 *** return (int) ((int) Duration(profile) / x); 00049 *** 00050 *** } 00051 *** 00052 *** 00053 *** Author: J.W. Heikkila, Jr. 00054 *** 00055 *** Copyright: 00056 *** 00057 *** Confidential and Proprietary Source Code for 00058 *** Wild-Fire Gaming Systems, Inc. 00059 *** 437 Jamesway, Marion, Ohio 43302 00060 *** 00061 *** Revisions: 00062 *** 00063 *** 10/05/2000 - JWH - Original version. 00064 *** 00065 *** Copyright (c) 2000, Wild-Fire Gaming Systems, Inc. All rights reserved. 00066 *** 00067 *************************************************************************************************** 00068 *************************************************************************************************** 00069 */ 00070 00071 //hyp.ker.profiler.h 00072 //inclusion de WfProfiler dans le kernel d'Hyperion 02/05/01 Tycho 00073 //modification 02/05/01 Tycho 00074 00075 00076 #ifndef _WFPROFILER_H_ 00077 #define _WFPROFILER_H_ 00078 00079 #ifndef hypker_INSIDE 00080 #error Inclusion not allowed (include hyp.ker.extern.h instead) 00081 #endif 00082 00083 #ifdef hypker_SHOW_INCLUDES 00084 #pragma message( "hypker include : " __FILE__ ) 00085 #endif 00086 00087 00088 00089 //****************************************************************************************** 00090 //****************************************************************************************** 00091 // 00092 // Many compilers do not support the RDTSC and CPUID assembly commands. For those 00093 // compilers, we need to force feed these commands into the code directly. 00094 #define CPUID __asm _emit 0x0F __asm _emit 0xA2 00095 #define RDTSC __asm _emit 0x0F __asm _emit 0x31 00096 #define PUSHAD __asm _emit 0x60 00097 #define POPAD __asm _emit 0x61 00098 00099 00100 //****************************************************************************************** 00101 //****************************************************************************************** 00102 // 00103 // Starts the Clock Cycle Counter... 00104 #define wf_START_NOW(pro) __asm \ 00105 { /* Actual Reason for Instruction: */ \ 00106 __asm PUSHAD /* Save all registers before we begin... */ \ 00107 __asm CPUID /* Tell the CPU to Serialize Instruction Execution */ \ 00108 __asm MOV [pro].Started, 1 /* Show we have started this profiler going */ \ 00109 __asm RDTSC /* Read the CPU Clock Cycle Count */ \ 00110 __asm MOV [pro].StartHigh, EDX /* Move the High DWORD into the Profile settings (start) */ \ 00111 __asm MOV [pro].StartLow, EAX /* Move the Low DWORD into the Profile settings (start) */ \ 00112 __asm POPAD /* Restore the registers the way they were */ \ 00113 } 00114 00115 00116 00117 //****************************************************************************************** 00118 //****************************************************************************************** 00119 // 00120 // Stops the Clock Cycle Counter... 00121 #define wf_STOP_NOW(pro) __asm \ 00122 { /* Actual Reason for Instruction: */ \ 00123 __asm PUSHAD /* Save all registers before we begin... */ \ 00124 __asm CPUID /* Tell the CPU to Serialize Instruction Execution */ \ 00125 __asm MOV [pro].Started, 0 /* Show we have finished this profiler test */ \ 00126 __asm RDTSC /* Read the CPU Clock Cycle Count */ \ 00127 __asm MOV [pro].EndHigh, EDX /* Move the High DWORD into the Profile settings (end) */ \ 00128 __asm MOV [pro].EndLow, EAX /* Move the Low DWORD into the Profile settings (end) */ \ 00129 __asm POPAD /* Restore the registers the way they were */ \ 00130 } 00131 00132 00133 00134 //****************************************************************************************** 00135 //****************************************************************************************** 00136 // 00137 // In order to get an accurate reading, we have to run the StartNow() 00138 // four times. We will take a base time from the last time SartNow() 00139 // was executed until the StopNow() below is executed. This will give 00140 // us an idea of how long it takes to execute the instructions from 00141 // the RDTSC in StartNow() until the RDTSC in StopNow(). Store this 00142 // as the Base Value and then we start the profiling... 00143 // 00144 #define wf_START(p) \ 00145 { \ 00146 wf_START_NOW(p); \ 00147 wf_STOP_NOW(p); \ 00148 ::hyp::hypker::SetDuration(p);\ 00149 wf_START_NOW(p); \ 00150 wf_STOP_NOW(p); \ 00151 ::hyp::hypker::SetDuration(p);\ 00152 wf_START_NOW(p); \ 00153 wf_STOP_NOW(p); \ 00154 ::hyp::hypker::SetDuration(p);\ 00155 wf_START_NOW(p); \ 00156 wf_STOP_NOW(p); \ 00157 ::hyp::hypker::SetDuration(p);\ 00158 wf_STOP_NOW(p); \ 00159 } 00160 00161 00162 00163 //****************************************************************************************** 00164 //****************************************************************************************** 00165 // 00166 // I think this is self-explanatory... 00167 #define wf_STOP(p) wf_STOP_NOW(p); 00168 00169 00170 struct WF_Profiler { 00171 unsigned Base; 00172 unsigned StartHigh; 00173 unsigned StartLow; 00174 unsigned EndHigh; 00175 unsigned EndLow; 00176 unsigned Started; 00177 }; 00178 00179 hyp_ker_DLL void Clear(WF_Profiler& data); 00180 hyp_ker_DLL t_int64 Duration(const WF_Profiler& data); 00181 hyp_ker_DLL void SetDuration(WF_Profiler& data); 00182 hyp_ker_DLL void Reset(WF_Profiler& data); 00183 00184 00185 00186 00187 00188 #endif // _WFPROFILER_H_ 00189
|
|