1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/tools/ctestfw/unicode/utimer.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,280 @@ 1.4 +/* 1.5 +************************************************************************ 1.6 +* Copyright (c) 1997-2012, International Business Machines 1.7 +* Corporation and others. All Rights Reserved. 1.8 +************************************************************************ 1.9 +*/ 1.10 + 1.11 +#ifndef _UTIMER_H 1.12 +#define _UTIMER_H 1.13 + 1.14 +#include "unicode/utypes.h" 1.15 + 1.16 +#if U_PLATFORM_HAS_WIN32_API 1.17 +# define VC_EXTRALEAN 1.18 +# define WIN32_LEAN_AND_MEAN 1.19 +# include <windows.h> 1.20 +#else 1.21 +# if U_PLATFORM == U_PF_OS390 && !defined(__UU) 1.22 +# define __UU /* Universal Unix - for struct timeval */ 1.23 +# endif 1.24 +# include <time.h> 1.25 +# include <sys/time.h> 1.26 +# include <unistd.h> 1.27 +#endif 1.28 + 1.29 +/** 1.30 + * This API provides functions for performing performance measurement 1.31 + * There are 3 main usage scenarios. 1.32 + * i) Loop until a threshold time is reached: 1.33 + * Example: 1.34 + * <code> 1.35 + * typedef Params Params; 1.36 + * struct Params{ 1.37 + * UChar* target; 1.38 + * int32_t targetLen; 1.39 + * const UChar* source; 1.40 + * int32_t sourceLen; 1.41 + * UNormalizationMode mode; 1.42 + * } 1.43 + * void NormFn( void* param){ 1.44 + * Params* parameters = ( Params*) param; 1.45 + * UErrorCode error = U_ZERO_ERROR; 1.46 + * unorm_normalize(parameters->source, parameters->sourceLen, parameters->mode, 0, parameters->target, parameters->targetLen, &error); 1.47 + * if(U_FAILURE(error)){ 1.48 + * printf("Normalization failed\n"); 1.49 + * } 1.50 + * } 1.51 + * 1.52 + * int main(){ 1.53 + * // time the normalization function 1.54 + * double timeTaken = 0; 1.55 + * Params param; 1.56 + * param.source // set up the source buffer 1.57 + * param.target // set up the target buffer 1.58 + * .... so on ... 1.59 + * UTimer timer; 1.60 + * // time the loop for 10 seconds at least and find out the loop count and time taken 1.61 + * timeTaken = utimer_loopUntilDone((double)10,(void*) param, NormFn, &loopCount); 1.62 + * } 1.63 + * </code> 1.64 + * 1.65 + * ii) Measure the time taken 1.66 + * Example: 1.67 + * <code> 1.68 + * double perfNormalization(NormFn fn,const char* mode,Line* fileLines,int32_t loopCount){ 1.69 + * int line; 1.70 + * int loops; 1.71 + * UErrorCode error = U_ZERO_ERROR; 1.72 + * UChar* dest=NULL; 1.73 + * int32_t destCapacity=0; 1.74 + * int len =-1; 1.75 + * double elapsedTime = 0; 1.76 + * int retVal=0; 1.77 + * 1.78 + * UChar arr[5000]; 1.79 + * dest=arr; 1.80 + * destCapacity = 5000; 1.81 + * UTimer start; 1.82 + * 1.83 + * // Initialize cache and ensure the data is loaded. 1.84 + * // This loop checks for errors in Normalization. Once we pass the initialization 1.85 + * // without errors we can safelly assume that there are no errors while timing the 1.86 + * // funtion 1.87 + * for (loops=0; loops<10; loops++) { 1.88 + * for (line=0; line < gNumFileLines; line++) { 1.89 + * if (opt_uselen) { 1.90 + * len = fileLines[line].len; 1.91 + * } 1.92 + * 1.93 + * retVal= fn(fileLines[line].name,len,dest,destCapacity,&error); 1.94 + * #if U_PLATFORM_HAS_WIN32_API 1.95 + * if(retVal==0 ){ 1.96 + * fprintf(stderr,"Normalization of string in Windows API failed for mode %s. ErrorNo: %i at line number %i\n",mode,GetLastError(),line); 1.97 + * return 0; 1.98 + * } 1.99 + * #endif 1.100 + * if(U_FAILURE(error)){ 1.101 + * fprintf(stderr,"Normalization of string in ICU API failed for mode %s. Error: %s at line number %i\n",mode,u_errorName(error),line); 1.102 + * return 0; 1.103 + * } 1.104 + * 1.105 + * } 1.106 + * } 1.107 + * 1.108 + * //compute the time 1.109 + * 1.110 + * utimer_getTime(&start); 1.111 + * for (loops=0; loops<loopCount; loops++) { 1.112 + * for (line=0; line < gNumFileLines; line++) { 1.113 + * if (opt_uselen) { 1.114 + * len = fileLines[line].len; 1.115 + * } 1.116 + * 1.117 + * retVal= fn(fileLines[line].name,len,dest,destCapacity,&error); 1.118 + * 1.119 + * } 1.120 + * } 1.121 + * 1.122 + * return utimer_getElapsedSeconds(&start); 1.123 + * } 1.124 + * </code> 1.125 + * 1.126 + * iii) Let a higher level function do the calculation of confidence levels etc. 1.127 + * Example: 1.128 + * <code> 1.129 + * void perf(UTimer* timer, UChar* source, int32_t sourceLen, UChar* target, int32_t targetLen, int32_t loopCount,UNormalizationMode mode, UErrorCode* error){ 1.130 + * int32_t loops; 1.131 + * for (loops=0; loops<loopCount; loops++) { 1.132 + * unorm_normalize(source,sourceLen,target, targetLen,mode,error); 1.133 + * } 1.134 + * utimer_getTime(timer); 1.135 + * } 1.136 + * void main(const char* argsc, int argv){ 1.137 + * // read the file and setup the data 1.138 + * // set up options 1.139 + * UTimer start,timer1, timer2, timer3, timer4; 1.140 + * double NFDTimeTaken, NFCTimeTaken, FCDTimeTaken; 1.141 + * switch(opt){ 1.142 + * case 0: 1.143 + * utimer_getTime(start); 1.144 + * perf(timer1, source,sourceLen, target, targetLen,loopCount,UNORM_NFD,&error); 1.145 + * NFDTimeTaken = utimer_getDeltaSeconds(start,timer1); 1.146 + * case 1: 1.147 + * timer_getTime(start); 1.148 + * perf(timer2,source,sourceLen,target,targetLen,loopCount,UNORM_NFC,&error); 1.149 + * NFCTimeTaken = utimer_getDeltaSeconds(start,timer2); 1.150 + * perf(timer3, source, sourceLen, target,targetLen, loopCount, UNORM_FCD,&error); 1.151 + * // ........so on ............. 1.152 + * } 1.153 + * // calculate confidence levels etc and print 1.154 + * 1.155 + * } 1.156 + * 1.157 + * </code> 1.158 + * 1.159 + */ 1.160 + 1.161 +typedef struct UTimer UTimer; 1.162 + 1.163 +typedef void FuntionToBeTimed(void* param); 1.164 + 1.165 + 1.166 +#if U_PLATFORM_HAS_WIN32_API 1.167 + 1.168 + struct UTimer{ 1.169 + LARGE_INTEGER start; 1.170 + LARGE_INTEGER placeHolder; 1.171 + }; 1.172 + 1.173 +static int uprv_initFrequency(UTimer* timer) 1.174 + { 1.175 + return QueryPerformanceFrequency(&timer->placeHolder); 1.176 + } 1.177 +static void uprv_start(UTimer* timer) 1.178 + { 1.179 + QueryPerformanceCounter(&timer->start); 1.180 + } 1.181 +static double uprv_delta(UTimer* timer1, UTimer* timer2){ 1.182 + return ((double)(timer2->start.QuadPart - timer1->start.QuadPart))/((double)timer1->placeHolder.QuadPart); 1.183 + } 1.184 +static UBool uprv_compareFrequency(UTimer* timer1, UTimer* timer2){ 1.185 + return (timer1->placeHolder.QuadPart == timer2->placeHolder.QuadPart); 1.186 + } 1.187 + 1.188 +#else 1.189 + 1.190 + struct UTimer{ 1.191 + struct timeval start; 1.192 + struct timeval placeHolder; 1.193 + }; 1.194 + 1.195 +static int32_t uprv_initFrequency(UTimer* /*timer*/) 1.196 + { 1.197 + return 0; 1.198 + } 1.199 +static void uprv_start(UTimer* timer) 1.200 + { 1.201 + gettimeofday(&timer->start, 0); 1.202 + } 1.203 +static double uprv_delta(UTimer* timer1, UTimer* timer2){ 1.204 + double t1, t2; 1.205 + 1.206 + t1 = (double)timer1->start.tv_sec + (double)timer1->start.tv_usec/(1000*1000); 1.207 + t2 = (double)timer2->start.tv_sec + (double)timer2->start.tv_usec/(1000*1000); 1.208 + return (t2-t1); 1.209 + } 1.210 +static UBool uprv_compareFrequency(UTimer* /*timer1*/, UTimer* /*timer2*/){ 1.211 + return TRUE; 1.212 + } 1.213 + 1.214 +#endif 1.215 +/** 1.216 + * Intializes the timer with the current time 1.217 + * 1.218 + * @param timer A pointer to UTimer struct to recieve the current time 1.219 + */ 1.220 +static inline void U_EXPORT2 1.221 +utimer_getTime(UTimer* timer){ 1.222 + uprv_initFrequency(timer); 1.223 + uprv_start(timer); 1.224 +} 1.225 + 1.226 +/** 1.227 + * Returns the difference in times between timer1 and timer2 by subtracting 1.228 + * timer1's time from timer2's time 1.229 + * 1.230 + * @param timer1 A pointer to UTimer struct to be used as starting time 1.231 + * @param timer2 A pointer to UTimer struct to be used as end time 1.232 + * @return Time in seconds 1.233 + */ 1.234 +static inline double U_EXPORT2 1.235 +utimer_getDeltaSeconds(UTimer* timer1, UTimer* timer2){ 1.236 + if(uprv_compareFrequency(timer1,timer2)){ 1.237 + return uprv_delta(timer1,timer2); 1.238 + } 1.239 + /* got error return -1 */ 1.240 + return -1; 1.241 +} 1.242 + 1.243 +/** 1.244 + * Returns the time elapsed from the starting time represented by the 1.245 + * UTimer struct pointer passed 1.246 + * @param timer A pointer to UTimer struct to be used as starting time 1.247 + * @return Time elapsed in seconds 1.248 + */ 1.249 +static inline double U_EXPORT2 1.250 +utimer_getElapsedSeconds(UTimer* timer){ 1.251 + UTimer temp; 1.252 + utimer_getTime(&temp); 1.253 + return uprv_delta(timer,&temp); 1.254 +} 1.255 + 1.256 +/** 1.257 + * Executes the function pointed to for a given time and returns exact time 1.258 + * taken and number of iterations of the loop 1.259 + * @param thresholTimeVal 1.260 + * @param loopCount output param to recieve the number of iterations 1.261 + * @param fn The funtion to be executed 1.262 + * @param param Parameters to be passed to the fn 1.263 + * @return the time elapsed in seconds 1.264 + */ 1.265 +static inline double U_EXPORT2 1.266 +utimer_loopUntilDone(double thresholdTimeVal, 1.267 + int32_t* loopCount, 1.268 + FuntionToBeTimed fn, 1.269 + void* param){ 1.270 + UTimer timer; 1.271 + double currentVal=0; 1.272 + *loopCount = 0; 1.273 + utimer_getTime(&timer); 1.274 + for(;currentVal<thresholdTimeVal;){ 1.275 + fn(param); 1.276 + currentVal = utimer_getElapsedSeconds(&timer); 1.277 + (*loopCount)++; 1.278 + } 1.279 + return currentVal; 1.280 +} 1.281 + 1.282 +#endif 1.283 +