Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

hyp.ker.profiler.h

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 

Top of Page
written by Pierre Rebours © 2000-2001. Terms of Use.