OLD | NEW |
(Empty) | |
| 1 /* |
| 2 ************************************************************************ |
| 3 * Copyright (c) 1997-2010, International Business Machines |
| 4 * Corporation and others. All Rights Reserved. |
| 5 ************************************************************************ |
| 6 */ |
| 7 |
| 8 #ifndef _UTIMER_H |
| 9 #define _UTIMER_H |
| 10 |
| 11 #include "unicode/utypes.h" |
| 12 |
| 13 #if defined(U_WINDOWS) |
| 14 # define VC_EXTRALEAN |
| 15 # define WIN32_LEAN_AND_MEAN |
| 16 # include <windows.h> |
| 17 #else |
| 18 # if defined(OS390) |
| 19 # define __UU /* Universal Unix - for struct timeval */ |
| 20 # endif |
| 21 # include <time.h> |
| 22 # include <sys/time.h> |
| 23 # include <unistd.h> |
| 24 #endif |
| 25 |
| 26 /** |
| 27 * This API provides functions for performing performance measurement |
| 28 * There are 3 main usage scenarios. |
| 29 * i) Loop until a threshold time is reached: |
| 30 * Example: |
| 31 * <code> |
| 32 * typedef Params Params; |
| 33 * struct Params{ |
| 34 * UChar* target; |
| 35 * int32_t targetLen; |
| 36 * const UChar* source; |
| 37 * int32_t sourceLen; |
| 38 * UNormalizationMode mode; |
| 39 * } |
| 40 * void NormFn( void* param){ |
| 41 * Params* parameters = ( Params*) param; |
| 42 * UErrorCode error = U_ZERO_ERROR; |
| 43 * unorm_normalize(parameters->source, parameters->sourceLen, parameter
s->mode, 0, parameters->target, parameters->targetLen, &error); |
| 44 * if(U_FAILURE(error)){ |
| 45 * printf("Normalization failed\n"); |
| 46 * } |
| 47 * } |
| 48 * |
| 49 * int main(){ |
| 50 * // time the normalization function |
| 51 * double timeTaken = 0; |
| 52 * Params param; |
| 53 * param.source // set up the source buffer |
| 54 * param.target // set up the target buffer |
| 55 * .... so on ... |
| 56 * UTimer timer; |
| 57 * // time the loop for 10 seconds at least and find out the loop count
and time taken |
| 58 * timeTaken = utimer_loopUntilDone((double)10,(void*) param, NormFn, &
loopCount); |
| 59 * } |
| 60 * </code> |
| 61 * |
| 62 * ii) Measure the time taken |
| 63 * Example: |
| 64 * <code> |
| 65 * double perfNormalization(NormFn fn,const char* mode,Line* fileLines,int3
2_t loopCount){ |
| 66 * int line; |
| 67 * int loops; |
| 68 * UErrorCode error = U_ZERO_ERROR; |
| 69 * UChar* dest=NULL; |
| 70 * int32_t destCapacity=0; |
| 71 * int len =-1; |
| 72 * double elapsedTime = 0; |
| 73 * int retVal=0; |
| 74 * |
| 75 * UChar arr[5000]; |
| 76 * dest=arr; |
| 77 * destCapacity = 5000; |
| 78 * UTimer start; |
| 79 * |
| 80 * // Initialize cache and ensure the data is loaded. |
| 81 * // This loop checks for errors in Normalization. Once we pass the in
itialization |
| 82 * // without errors we can safelly assume that there are no errors whi
le timing the |
| 83 * // funtion |
| 84 * for (loops=0; loops<10; loops++) { |
| 85 * for (line=0; line < gNumFileLines; line++) { |
| 86 * if (opt_uselen) { |
| 87 * len = fileLines[line].len; |
| 88 * } |
| 89 * |
| 90 * retVal= fn(fileLines[line].name,len,dest,destCapacity,&error
); |
| 91 * #if defined(U_WINDOWS) |
| 92 * if(retVal==0 ){ |
| 93 * fprintf(stderr,"Normalization of string in Windows API f
ailed for mode %s. ErrorNo: %i at line number %i\n",mode,GetLastError(),line); |
| 94 * return 0; |
| 95 * } |
| 96 * #endif |
| 97 * if(U_FAILURE(error)){ |
| 98 * fprintf(stderr,"Normalization of string in ICU API faile
d for mode %s. Error: %s at line number %i\n",mode,u_errorName(error),line); |
| 99 * return 0; |
| 100 * } |
| 101 * |
| 102 * } |
| 103 * } |
| 104 * |
| 105 * //compute the time |
| 106 * |
| 107 * utimer_getTime(&start); |
| 108 * for (loops=0; loops<loopCount; loops++) { |
| 109 * for (line=0; line < gNumFileLines; line++) { |
| 110 * if (opt_uselen) { |
| 111 * len = fileLines[line].len; |
| 112 * } |
| 113 * |
| 114 * retVal= fn(fileLines[line].name,len,dest,destCapacity,&error
); |
| 115 * |
| 116 * } |
| 117 * } |
| 118 * |
| 119 * return utimer_getElapsedSeconds(&start); |
| 120 * } |
| 121 * </code> |
| 122 * |
| 123 * iii) Let a higher level function do the calculation of confidence levels etc. |
| 124 * Example: |
| 125 * <code> |
| 126 * void perf(UTimer* timer, UChar* source, int32_t sourceLen, UChar* targe
t, int32_t targetLen, int32_t loopCount,UNormalizationMode mode, UErrorCode* err
or){ |
| 127 * int32_t loops; |
| 128 * for (loops=0; loops<loopCount; loops++) { |
| 129 * unorm_normalize(source,sourceLen,target, targetLen,mode,erro
r); |
| 130 * } |
| 131 * utimer_getTime(timer); |
| 132 * } |
| 133 * void main(const char* argsc, int argv){ |
| 134 * // read the file and setup the data |
| 135 * // set up options |
| 136 * UTimer start,timer1, timer2, timer3, timer4; |
| 137 * double NFDTimeTaken, NFCTimeTaken, FCDTimeTaken; |
| 138 * switch(opt){ |
| 139 * case 0: |
| 140 * utimer_getTime(start); |
| 141 * perf(timer1, source,sourceLen, target, targetLen,loopCount,U
NORM_NFD,&error); |
| 142 * NFDTimeTaken = utimer_getDeltaSeconds(start,timer1); |
| 143 * case 1: |
| 144 * timer_getTime(start); |
| 145 * perf(timer2,source,sourceLen,target,targetLen,loopCount,UNOR
M_NFC,&error); |
| 146 * NFCTimeTaken = utimer_getDeltaSeconds(start,timer2); |
| 147 * perf(timer3, source, sourceLen, target,targetLen, loopCount,
UNORM_FCD,&error); |
| 148 * // ........so on ............. |
| 149 * } |
| 150 * // calculate confidence levels etc and print |
| 151 * |
| 152 * } |
| 153 * |
| 154 * </code> |
| 155 * |
| 156 */ |
| 157 |
| 158 typedef struct UTimer UTimer; |
| 159 |
| 160 typedef void FuntionToBeTimed(void* param); |
| 161 |
| 162 |
| 163 #if defined(U_WINDOWS) |
| 164 |
| 165 struct UTimer{ |
| 166 LARGE_INTEGER start; |
| 167 LARGE_INTEGER placeHolder; |
| 168 }; |
| 169 |
| 170 int uprv_initFrequency(UTimer* timer) |
| 171 { |
| 172 return QueryPerformanceFrequency(&timer->placeHolder); |
| 173 } |
| 174 void uprv_start(UTimer* timer) |
| 175 { |
| 176 QueryPerformanceCounter(&timer->start); |
| 177 } |
| 178 double uprv_delta(UTimer* timer1, UTimer* timer2){ |
| 179 return ((double)(timer2->start.QuadPart - timer1->start.QuadPart))/((dou
ble)timer1->placeHolder.QuadPart); |
| 180 } |
| 181 UBool uprv_compareFrequency(UTimer* timer1, UTimer* timer2){ |
| 182 return (timer1->placeHolder.QuadPart == timer2->placeHolder.QuadPart); |
| 183 } |
| 184 |
| 185 #else |
| 186 |
| 187 struct UTimer{ |
| 188 struct timeval start; |
| 189 struct timeval placeHolder; |
| 190 }; |
| 191 |
| 192 int32_t uprv_initFrequency(UTimer* /*timer*/) |
| 193 { |
| 194 return 0; |
| 195 } |
| 196 void uprv_start(UTimer* timer) |
| 197 { |
| 198 gettimeofday(&timer->start, 0); |
| 199 } |
| 200 double uprv_delta(UTimer* timer1, UTimer* timer2){ |
| 201 double t1, t2; |
| 202 |
| 203 t1 = (double)timer1->start.tv_sec + (double)timer1->start.tv_usec/(1000
*1000); |
| 204 t2 = (double)timer2->start.tv_sec + (double)timer2->start.tv_usec/(1000
*1000); |
| 205 return (t2-t1); |
| 206 } |
| 207 UBool uprv_compareFrequency(UTimer* /*timer1*/, UTimer* /*timer2*/){ |
| 208 return TRUE; |
| 209 } |
| 210 |
| 211 #endif |
| 212 /** |
| 213 * Intializes the timer with the current time |
| 214 * |
| 215 * @param timer A pointer to UTimer struct to recieve the current time |
| 216 */ |
| 217 static U_INLINE void U_EXPORT2 |
| 218 utimer_getTime(UTimer* timer){ |
| 219 uprv_initFrequency(timer); |
| 220 uprv_start(timer); |
| 221 } |
| 222 |
| 223 /** |
| 224 * Returns the difference in times between timer1 and timer2 by subtracting |
| 225 * timer1's time from timer2's time |
| 226 * |
| 227 * @param timer1 A pointer to UTimer struct to be used as starting time |
| 228 * @param timer2 A pointer to UTimer struct to be used as end time |
| 229 * @return Time in seconds |
| 230 */ |
| 231 static U_INLINE double U_EXPORT2 |
| 232 utimer_getDeltaSeconds(UTimer* timer1, UTimer* timer2){ |
| 233 if(uprv_compareFrequency(timer1,timer2)){ |
| 234 return uprv_delta(timer1,timer2); |
| 235 } |
| 236 /* got error return -1 */ |
| 237 return -1; |
| 238 } |
| 239 |
| 240 /** |
| 241 * Returns the time elapsed from the starting time represented by the |
| 242 * UTimer struct pointer passed |
| 243 * @param timer A pointer to UTimer struct to be used as starting time |
| 244 * @return Time elapsed in seconds |
| 245 */ |
| 246 static U_INLINE double U_EXPORT2 |
| 247 utimer_getElapsedSeconds(UTimer* timer){ |
| 248 UTimer temp; |
| 249 utimer_getTime(&temp); |
| 250 return uprv_delta(timer,&temp); |
| 251 } |
| 252 |
| 253 /** |
| 254 * Executes the function pointed to for a given time and returns exact time |
| 255 * taken and number of iterations of the loop |
| 256 * @param thresholTimeVal |
| 257 * @param loopCount output param to recieve the number of iterations |
| 258 * @param fn The funtion to be executed |
| 259 * @param param Parameters to be passed to the fn |
| 260 * @return the time elapsed in seconds |
| 261 */ |
| 262 static U_INLINE double U_EXPORT2 |
| 263 utimer_loopUntilDone(double thresholdTimeVal, |
| 264 int32_t* loopCount, |
| 265 FuntionToBeTimed fn, |
| 266 void* param){ |
| 267 UTimer timer; |
| 268 double currentVal=0; |
| 269 *loopCount = 0; |
| 270 utimer_getTime(&timer); |
| 271 for(;currentVal<thresholdTimeVal;){ |
| 272 fn(param); |
| 273 currentVal = utimer_getElapsedSeconds(&timer); |
| 274 (*loopCount)++; |
| 275 } |
| 276 return currentVal; |
| 277 } |
| 278 |
| 279 #endif |
| 280 |
OLD | NEW |