00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
#include <config.h>
00016
00017
namespace SH
00018 {
00019
00020
#define MEASUREMENT_MODE 0 // dont measure anything
00021
00022
00023
00024
00025
#define MEASURE_1(point)
00026
#define MEASUREB_1(point,sub)
00027
#define MEASUREFLUSH
00028
#define MEASURE_2(point)
00029
#define MEASUREB_2(point,sub)
00030
#define MEASURE_3(point)
00031
#define MEASUREGET_3(dest)
00032
#define MEASURESTORE_3(dest,point)
00033
#if MEASUREMENT_MODE == 0
00034
# undef HAVE_PENTIUM_PROBE
00035
#elif MEASUREMENT_MODE == 1
00036
# undef MEASURE_1
00037
# undef MEASUREB_1
00038
# undef MEASUREFLUSH
00039
# define MEASURE_1(point) Measurement::measure( point );
00040
# define MEASUREB_1(point,sub) Measurement::measure( point,sub );
00041
# define MEASUREFLUSH Measurement::flushpipe( );
00042
#elif MEASUREMENT_MODE == 2
00043
# undef MEASURE_2
00044
# undef MEASUREB_2
00045
# define MEASURE_2(point) Measurement::measure( point );
00046
# define MEASUREB_2(point,sub) Measurement::measure( point,sub );
00047
#elif MEASUREMENT_MODE == 3
00048
# undef MEASURE_3
00049
# undef MEASUREGET_3
00050
# undef MEASURESTORE_3
00051
# define MEASURE_3(point) Measurement::measure( point );
00052
# define MEASUREGET_3(dest) Measurement::measure_get( dest );
00053
# define MEASURESTORE_3(dest,point) Measurement::measure_store( dest, point );
00054
#endif
00055
00056 class Measurement
00057 {
00058
public:
00059 enum Index
00060 {
00061
Begin,
00062
00063
#if MEASUREMENT_MODE == 2
00064
BeforeCode,
00065
EnterCode,
00066
LeaveCode,
00067
AfterCode,
00068
#endif
00069
00070
#if (MEASUREMENT_MODE == 1) | (MEASUREMENT_MODE == 2)
00071
BeforePull,
00072
EnterPull,
00073
LeavePull,
00074
AfterPull,
00075
00076
BeforePush,
00077
EnterPush,
00078
LeavePush,
00079
AfterPush,
00080
#endif
00081
00082
End,
00083
NumMeasurements
00084 };
00085
00086
#ifdef HAVE_PENTIUM_PROBE
00087 inline static void flushpipe( )
00088 {
00089 __asm __volatile(
"push %eax\n"
00090
"push %ebx\n"
00091
"push %ecx\n"
00092
"push %edx\n"
00093
"cpuid\n"
00094
"pop %edx\n"
00095
"pop %ecx\n"
00096
"pop %ebx\n"
00097
"pop %eax\n" );
00098 }
00099
00100 inline static void measure( Measurement::Index i,
int subcodepoint=0 )
00101 {
00102
if( _first ) init( );
00103
00104
00105
00106
00107 __asm __volatile(
".byte 0x0f,0x31" :
"=A" (cur->
entry[i]));
00108
00109 Measurement::_codepoint[i][subcodepoint] += 1;
00110
00111
if( i ==
End )
00112 {
00113 cur++;
00114
if( cur == _last )
00115 {
00116 dump();
00117 }
00118 }
00119 }
00120
00121 inline static void measure_get( u_int64_t& dest )
00122 {
00123 __asm __volatile(
".byte 0x0f,0x31" :
"=A" (dest));
00124 }
00125
00126 inline static void measure_store( u_int64_t dest, Measurement::Index i,
int subcodepoint=0 )
00127 {
00128
if( _first ) init( );
00129 cur->
entry[i] = dest;
00130 Measurement::_codepoint[i][subcodepoint] += 1;
00131
00132
if( i ==
End )
00133 {
00134 cur++;
00135
if( cur == _last )
00136 {
00137 dump();
00138 }
00139 }
00140 }
00141
00142
private:
00143 u_int64_t entry[NumMeasurements];
00144
00145
static const size_t _max_cycles = 2000000;
00146
static bool _first;
00147
static Measurement* _array;
00148
static Measurement* cur;
00149
static Measurement* _last;
00150
static size_t _codepoint[NumMeasurements][3];
00151
00152
static void init( );
00153
static void dump( );
00154
00155
#else
00156
inline static void measure( Measurement::Index,
int=0 ) { }
00157
#endif
00158
00159
friend class Stat;
00160 };
00161
00162 };
00163