intl/icu/source/tools/ctestfw/unicode/utimer.h

changeset 0
6474c204b198
     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 +

mercurial