From 7c6644442b3b8b84a53e02a54be9cf2866b2ca91 Mon Sep 17 00:00:00 2001 From: deepakv Date: Thu, 23 Oct 2014 12:10:18 -0700 Subject: [PATCH] Using QueryPerformancecounter to measure latency in redis-benchmark.exe Redis-benchmark on windows seems to be not able to calculate the time granularity in micro seconds. Came across this article http://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx and updated the benchmark for latency measurements accordingly. Windows: Following is output from windows for micro seconds taken for each request. Where for any request taking less than 1 ms is being calculated as 0 redis-benchmark.exe -h -a pwd -c 1 -d 1024 -t get -n 10 0,0,0,0,0,0,0,0 Linux: src/redis-benchmark -h -a pwd -c 1 -d 1024 -t get -n 10 792,800,808,820,837,845,888,891,971,2498 After the change on windows now it shows following: 796,809,887,890,893,943,944,974 --- src/redis-benchmark.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/redis-benchmark.c b/src/redis-benchmark.c index 777e37dc..a8859a74 100644 --- a/src/redis-benchmark.c +++ b/src/redis-benchmark.c @@ -107,6 +107,28 @@ typedef struct _client { static void writeHandler(aeEventLoop *el, int fd, void *privdata, int mask); static void createMissingClients(client c); +#ifdef WIN32_IOCP +/*acquires high resolution time stamps on windows, more details can be found here http://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx */ +static long long getQPCTimeStamp() +{ + LARGE_INTEGER time; + QueryPerformanceCounter(&time); + return time.QuadPart; +} +static long long getQPCElapsedMicroSeconds(long long startime, long long endtime) +{ + long long elapsedMicroseconds = endtime - startime; + LARGE_INTEGER Frequency; + QueryPerformanceFrequency(&Frequency); + + // To guard against loss-of-precision, we convert + // to microseconds *before* dividing by ticks-per-second. + elapsedMicroseconds *= 1000000; + elapsedMicroseconds /= Frequency.QuadPart; + return elapsedMicroseconds; +} +#endif + /* Implementation */ static long long ustime(void) { struct timeval tv; @@ -210,7 +232,14 @@ static void readHandler(aeEventLoop *el, int fd, void *privdata, int mask) { /* Calculate latency only for the first read event. This means that the * server already sent the reply and we need to parse it. Parsing overhead * is not part of the latency, so calculate it only once, here. */ - if (c->latency < 0) c->latency = ustime()-(c->start); + if (c->latency < 0) + { +#ifdef WIN32_IOCP + c->latency = getQPCElapsedMicroSeconds(c->start, getQPCTimeStamp()); +#else + c->latency = ustime() - (c->start); +#endif + } #ifdef WIN32_IOCP nread = read(c->context->fd,buf,sizeof(buf)); @@ -305,7 +334,11 @@ static void writeHandler(aeEventLoop *el, int fd, void *privdata, int mask) { /* Really initialize: randomize keys and set start time. */ if (config.randomkeys) randomizeClientKey(c); - c->start = ustime(); +#ifdef WIN32_IOCP + c->start = getQPCTimeStamp(); +#else + c->start = ustime(); +#endif c->latency = -1; }