¿Qué debo usar para reemplazar gettimeofday() en Windows?
select winapi (4)
Estoy escribiendo una clase de Socket portátil que admite tiempos de espera tanto para enviar como para recibir ... Para implementar estos tiempos de espera, estoy usando select()
... Pero a veces necesito saber cuánto tiempo estuve bloqueado dentro de select()
que, por supuesto, en Linux implementaría llamando a gettimeofday()
antes y después de llamar a select()
y luego usando timersub()
para calcular el delta ...
Dado que select()
en Windows acepta struct timeval
para su tiempo de espera, ¿qué método debo usar para reemplazar gettimeofday () en Windows?
En su caso yo usaría la plataforma independiente std::clock
Puede consultar QueryPerformanceCounter y QueryPerformanceFrequency. Estos son de muy alta resolución, hasta una marca por cada diez ciclos en algunos temporizadores de hardware.
Qué tal si:
unsigned long start = GetTickCount();
// stuff that needs to be timed
unsigned long delta = GetTickCount() - start;
GetTickCount()
no es muy preciso, pero probablemente funcionará bien. Si ve muchos intervalos de 0, 16 o 31 milisegundos, intente cronometrar intervalos más largos o use una función más precisa como timeGetTime
.
Lo que suelo hacer es esto:
unsigned long deltastack;
int samples = 0;
float average;
unsigned long start = GetTickCount();
// stuff that needs to be timed
unsigned long delta = GetTickCount() - start;
deltastack += delta;
if (samples++ == 10)
{
// total time divided by amount of samples
average = (float)deltastack / 10.f;
deltastack = 0;
samples = 0;
}
Terminé encontrando esta página: gettimeofday () en windows [edit: enlace eliminado porque ahora apunta a un sitio de publicidad]. Que tiene una implementación práctica y elegante de gettimeofday () en Windows. Utiliza el método GetSystemTimeAsFileTime()
para obtener un reloj preciso.
Actualización : Aquí hay un enlace activo [editar: enlace eliminado porque ahora apunta a un sitio de publicidad] que apunta a la implementación a la que se refiere el OP. Tenga en cuenta también que hay un error tipográfico en la implementación vinculada:
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 // WRONG
#else
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL // WRONG
#endif
Los valores mostrados faltan un 0
extra al final (asumieron microsegundos, no el número de intervalos de 100 nanosegundos). Este error tipográfico se encontró a través de este comentario en una página de proyecto de código de Google. Los valores correctos a utilizar se muestran a continuación:
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 116444736000000000Ui64 // CORRECT
#else
#define DELTA_EPOCH_IN_MICROSECS 116444736000000000ULL // CORRECT
#endif
Implementación de PostgreSQL de gettimeofday para Windows:
/*
* gettimeofday.c
* Win32 gettimeofday() replacement
*
* src/port/gettimeofday.c
*
* Copyright (c) 2003 SRA, Inc.
* Copyright (c) 2003 SKC, Inc.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose, without fee, and without a
* written agreement is hereby granted, provided that the above
* copyright notice and this paragraph and the following two
* paragraphs appear in all copies.
*
* IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
* LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
* DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS
* IS" BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include "c.h"
#include <sys/time.h>
/* FILETIME of Jan 1 1970 00:00:00. */
static const unsigned __int64 epoch = ((unsigned __int64) 116444736000000000ULL);
/*
* timezone information is stored outside the kernel so tzp isn''t used anymore.
*
* Note: this function is not for Win32 high precision timing purpose. See
* elapsed_time().
*/
int
gettimeofday(struct timeval * tp, struct timezone * tzp)
{
FILETIME file_time;
SYSTEMTIME system_time;
ULARGE_INTEGER ularge;
GetSystemTime(&system_time);
SystemTimeToFileTime(&system_time, &file_time);
ularge.LowPart = file_time.dwLowDateTime;
ularge.HighPart = file_time.dwHighDateTime;
tp->tv_sec = (long) ((ularge.QuadPart - epoch) / 10000000L);
tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
return 0;
}