la risoluzione di std :: chrono :: high_resolution_clock non corrisponde alle misure

Lasciami fare la mia domanda con questo programma di test:

#include  #include  using std::chrono::nanoseconds; using std::chrono::duration_cast; int main(int argc, char* argv[]) { std::cout << "resolution (nano) = " << (double) std::chrono::high_resolution_clock::period::num / std::chrono::high_resolution_clock::period::den * 1000 * 1000 * 1000 << std::endl; auto t1 = std::chrono::high_resolution_clock::now(); std::cout << "how much nanoseconds std::cout takes?" << std::endl; auto t2 = std::chrono::high_resolution_clock::now(); auto diff = t2-t1; nanoseconds ns = duration_cast(diff); std::cout << "std::cout takes " << ns.count() << " nanoseconds" << std::endl; return 0; } 

Uscita sulla mia macchina:

risoluzione (nano) = 100

quanto nanosecondi std :: cout richiede?

std :: cout richiede 1000200 nanosecondi

Di conseguenza ricevo sia 1000200 o 1000300 o 1000400 o 1000500 o 1000600 o 2000600 (= 1 o 2 microsecondi). Ovviamente la risoluzione di std::chrono non è di 100 nano-secondi o il modo in cui misuro il tempo di std::cout è sbagliato. (perché non ricevo mai qualcosa tra 1 e 2 microsecondi, ad esempio 1500000 ?)

Ho bisogno di un timer ad alta risoluzione in C ++. Il sistema operativo stesso fornisce un timer ad alta risoluzione perché sono in grado di misurare le cose con precisione al microsecondo utilizzando la class C # Stopwatch sulla stessa macchina. Quindi avrei solo bisogno di usare correttamente il timer ad alta risoluzione del sistema operativo!

Come posso correggere il mio programma per produrre i risultati attesi?

Immagino che tu stia usando VS2012; Altrimenti, ignorare questa risposta. VS2012 typedef ‘s high_resolution_clock a system_clock . Purtroppo, questo significa che ha una precisione scadente (circa 1 ms). Ho scritto un orologio ad alta risoluzione migliore che utilizza QueryPerformanceCounter per l’uso in VS2012 …

HighResClock.h:

  struct HighResClock { typedef long long rep; typedef std::nano period; typedef std::chrono::duration duration; typedef std::chrono::time_point time_point; static const bool is_steady = true; static time_point now(); }; 

HighResClock.cpp:

 namespace { const long long g_Frequency = []() -> long long { LARGE_INTEGER frequency; QueryPerformanceFrequency(&frequency); return frequency.QuadPart; }(); } HighResClock::time_point HighResClock::now() { LARGE_INTEGER count; QueryPerformanceCounter(&count); return time_point(duration(count.QuadPart * static_cast(period::den) / g_Frequency)); } 

(Ho omesso un assert e #ifs per vedere se è stato compilato nel 2012 dal codice precedente)

Puoi usare questo orologio ovunque e allo stesso modo degli orologi standard.

La risoluzione di un orologio non è necessariamente uguale alla durata minima che può essere rappresentata dal tipo di dati utilizzato dall’orologio. In questo caso l’implementazione utilizza un tipo di dati che può rappresentare una durata di soli 100 nanosecondi, ma l’orologio sottostante non ha effettivamente una tale risoluzione.


La bassa risoluzione di high_resolution_clock di Visual Studio è stata un problema per diversi anni. Il manutentore della libreria standard Microsoft C ++, Stephan T. Lavavej, ha indicato che questo problema è stato risolto in VS2015 tramite l’uso di QueryPerformanceCounter() .

Forse l’implementazione non implementa il timer con risoluzione più elevata?

Sembra che tu stia usando Windows (hai menzionato C #) quindi se utilizzi un timer e stai effettivamente utilizzando Windows puoi usare QueryPerformanceFrequency e QueryPerformanceCounter .