2011-12-20 33 views
6

Estoy portando mi aplicación a windows desde unix y me he topado con una pared. En mi aplicación, necesito encontrar el tiempo en microsegundos (toda la aplicación depende en gran medida debido a que es una aplicación de alta precisión).timespec equivalente para windows

Anteriormente estaba usando la estructura timespec, pero Windows no contiene tal cosa. El comando GetTickCount no es suficiente porque devuelve el tiempo en milisegundos. También estaba pensando en QueryPerformanceFrequency.

Si alguien supiera algo tan idéntico como timespec como sea posible, en el futuro incluso podría necesitar nanosegundos, algo que no he buscado en Windows.

Gracias a cualquier persona por su ayuda

+0

¿Qué pasa con QueryPerformanceCounter? – kichik

+0

@kichik Escuché que no funciona bien cuando se usa con una CPU de doble núcleo. No sé si es completamente cierto o no – Quillion

+0

El nuevo tiempo de ejecución (incluido con vs2015, v14.0.xyz) incluye un encabezado que define un tipo de timespec (en realidad tres tipos diferentes: _timespec32, _timespec64 y timespec). Desafortunadamente, no hay una macro adjunta (por ejemplo, _TIMESPEC_DEFINED) para probar la presencia de este tipo (argh). –

Respuesta

10

Véase, por ejemplo, How to realise long-term high-resolution timing on windows using C++? y C++ Timer function to provide time in nano seconds.

He hecho algunas pruebas con Cygwin en Windows XP: en mi máquina, la granularidad de gettimeofday() es de aproximadamente 15 mseg (~ 1/64 seg). Lo cual es bastante grosero. Y también lo es la granularidad de:

* clock_t clock(void) (divisor CLOCKS_PER_SEC) 
* clock_t times(struct tms *) (divisor sysconf(_SC_CLK_TCK)) 

Ambos son divisores 1000 (POSIX puede tener 1.000.000 de primera).

Además, clock_getres (CLOCK_REALTIME, ...) devuelve 15 mseg, por lo que es poco probable que clock_gettime() ayude. Y CLOCK_MONOTONIC y CLOCK_PROCESS_CPUTIME_ID no funcionan.

Otras posibilidades para Windows pueden ser RDTSC; ver el artículo de Wikipedia. Y HPET, que no está disponible con Windows XP.

También tenga en cuenta que en Linux, clock() es la hora del proceso, mientras que en Windows es el tiempo de la pared.

Así algunos ejemplos de código, tanto para el estándar de Unix, y para el código CYGWIN se ejecuta en Windows, lo que da una granularidad de unos 50 microsegundos (en mi máquina). El valor de retorno está en segundos y da la cantidad de segundos transcurridos desde que se llamó por primera vez a la función. (Me di cuenta tardíamente de que se trataba de una respuesta que di sobre a year ago).

#ifndef __CYGWIN32__ 
double RealElapsedTime(void) { // returns 0 seconds first time called 
    static struct timeval t0; 
    struct timeval tv; 
    gettimeofday(&tv, 0); 
    if (!t0.tv_sec) 
     t0 = tv; 
    return tv.tv_sec - t0.tv_sec + (tv.tv_usec - t0.tv_usec)/1000000.; 
} 
#else 
#include <windows.h> 
double RealElapsedTime(void) { // granularity about 50 microsecs on my machine 
    static LARGE_INTEGER freq, start; 
    LARGE_INTEGER count; 
    if (!QueryPerformanceCounter(&count)) 
     FatalError("QueryPerformanceCounter"); 
    if (!freq.QuadPart) { // one time initialization 
     if (!QueryPerformanceFrequency(&freq)) 
     FatalError("QueryPerformanceFrequency"); 
     start = count; 
    } 
    return (double)(count.QuadPart - start.QuadPart)/freq.QuadPart; 
} 
#endif 
+0

En general, parece una respuesta sólida, pero no puedo entender por qué se devolverá un valor doble o qué representará.Entiendo que encuentras diferencia y luego divides por frecuencia. Entonces, si supongo que el valor doble está en segundos, entonces para encontrar microsegundos, tengo que multiplicar por 1 millón (1 000 000). ¿Está bien? – Quillion

+0

El valor de retorno está en 'segundos', y da la cantidad de segundos transcurridos desde que se llamó por primera vez a la función. –

+0

El [GNU C Lib Manual] (http://www.gnu.org/s/hello/manual/libc/Elapsed-Time.html) observa que '' hay algunos sistemas operativos peculiares donde el miembro tv_sec tiene un tipo sin signo . "'Para estos, el código anterior necesita un molde, o la suposición de que el reloj nunca se ejecuta hacia atrás. –

2

portátil entre Windows, UNIX, Linux y cualquier cosa vagamente moderna: std::chrono::high_resolution_clock. La resolución puede variar, pero puede averiguar en tiempo de compilación qué es. Nanosegundos es ciertamente posible en hardware moderno.

Tenga en cuenta que la precisión de nanosegundos realmente significa una precisión por debajo del metro. Un nanosegundo a velocidad de luz es solo de 30 centímetros. Mover su computadora desde la parte superior del bastidor hasta la parte inferior la está moviendo literalmente en varios nanosegundos.

Cuestiones relacionadas