2011-12-20 11 views
6

Sto trasferendo la mia domanda a windows da unix e ho incontrato un muro. Nella mia applicazione ho bisogno di trovare il tempo in microsecondi (l'intera applicazione dipende molto da esso perché è un'applicazione di alta precisione).voltepec equivalente per windows

Precedentemente stavo usando la struttura timespec, ma Windows non contiene nulla di simile. Il comando GetTickCount non è sufficiente perché restituisce il tempo in millisecondi. Stavo anche pensando a QueryPerformanceFrequency.

Qualcuno potrebbe sapere qualcosa che è identico a timespec possibile, in futuro potrei anche richiedere anche i nanosecondi, che nulla ho cercato in Windows supporta.

Grazie a chiunque per il loro aiuto

+0

Cosa c'è di sbagliato in QueryPerformanceCounter? – kichik

+0

@kichik Ho sentito che agisce in modo incerto se usato con una CPU dual core. Non so se è completamente vero o no – Quillion

+0

Il runtime nuovo (in bundle con vs2015, v14.0.xyz) include un'intestazione che definisce un tipo di timespec (in realtà tre tipi diversi: _timespec32, _timespec64 e timespec). Sfortunatamente, non esiste una macro di accompagnamento (es. _TIMESPEC_DEFINED) per verificare la presenza di questo tipo (argh). –

risposta

10

veda, ad esempio, How to realise long-term high-resolution timing on windows using C++? e C++ Timer function to provide time in nano seconds.

Ho eseguito alcuni test con Cygwin su Windows XP: sulla mia macchina, la granularità di gettimeofday() è di circa 15 msecs (~ 1/64 sec). Che è piuttosto grossolano. E così è la granularità di:

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

Entrambi i divisori sono 1000 (POSIX può avere per la prima 1000000).

Inoltre, clock_getres (CLOCK_REALTIME, ...) restituisce 15 msecs, quindi è improbabile che clock_gettime() aiuti. E CLOCK_MONOTONIC e CLOCK_PROCESS_CPUTIME_ID non funzionano.

Altre possibilità per Windows potrebbero essere RDTSC; guarda l'articolo di Wikipedia. E HPET, che non è disponibile con Windows XP.

Nota anche in Linux, clock() è il tempo di elaborazione, mentre in Windows è l'ora del muro.

Così alcuni esempi di codice, sia per lo standard Unix, e per il codice CYGWIN che funziona sotto Windows, che dà una granularità di circa 50 microsecondi (su mia macchina). Il valore restituito è espresso in secondi e indica il numero di secondi trascorsi da quando la funzione è stata chiamata per la prima volta. (Mi sono tardato a capire che era in una risposta che ho dato oltre 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

Tutto sommato sembra una risposta solida, ma non riesco a capire perché debba essere restituito un doppio valore o che cosa rappresenterà.Capisco che trovi la differenza e poi dividi per frequenza. Quindi se presumo che il doppio valore sia in secondi, allora per trovare microsecondi devo moltiplicare per 1 milione (1 000 000). È giusto? – Quillion

+0

Il valore di ritorno è in "secondi" e indica il numero di secondi trascorsi da quando la funzione è stata chiamata per la prima volta. –

+0

Il [Manuale GNU C Lib] (http://www.gnu.org/s/hello/manual/libc/Elapsed-Time.html) nota che ci sono "alcuni sistemi operativi particolari in cui il membro tv_sec ha un tipo non firmato . "Per questi, il codice di cui sopra ha bisogno di un cast, o il presupposto che l'orologio non corra mai all'indietro. –

2

portatile tra Windows, UNIX, Linux e qualsiasi cosa vagamente moderna: std::chrono::high_resolution_clock. La risoluzione può variare, ma puoi scoprire in fase di compilazione cos'è. I nanosecondi sono certamente possibili su hardware moderno.

Ricordare che la precisione di nanosecondi indica una precisione inferiore al metro. Un nanosecondo alla velocità della luce è di soli 30 centimetri. Spostare il computer dalla parte superiore del rack verso il basso significa letteralmente spostarlo di diversi nanosecondi.