time_point steady_clock c++ visual-studio-2012 c++11 chrono

c++ - steady_clock - resolución de std:: chrono:: high_resolution_clock no corresponde a medidas



std:: chrono:: steady_clock (3)

Déjame hacer mi pregunta mediante este programa de prueba:

#include <iostream> #include <chrono> 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<nanoseconds>(diff); std::cout << "std::cout takes " << ns.count() << " nanoseconds" << std::endl; return 0; }

Salida en mi máquina:

resolución (nano) = 100

¿Cuánto nanosegundos toma std :: cout?

std :: cout toma 1000200 nanosegundos

Recibo 1000200 o 1000300 o 1000400 o 1000500 o 1000600 o 2000600 como resultado (= 1 o 2 microsegundos). Obviamente, o bien la resolución de std::chrono no es de 100 nano segundos o la forma en que mido el tiempo de std::cout es incorrecta. (¿Por qué nunca recibo algo entre 1 y 2 microsegundos, por ejemplo 1500000 ?)

Necesito un temporizador de alta resolución en C ++. El sistema operativo en sí proporciona un temporizador de alta resolución porque puedo medir cosas con microsegundos de precisión usando la clase C # Stopwatch en la misma máquina. ¡Entonces solo necesitaría usar correctamente el temporizador de alta resolución que tiene el sistema operativo!

¿Cómo arreglo mi programa para producir los resultados esperados?


La resolución de un reloj no es necesariamente la misma que la menor duración que puede representarse mediante el tipo de datos que utiliza el reloj. En este caso, su implementación utiliza un tipo de datos que puede representar una duración tan pequeña como 100 nanosegundos, pero el reloj subyacente en realidad no tiene esa resolución.

La baja resolución de high_resolution_clock de Visual Studio ha sido un problema durante varios años. El mantenedor de la biblioteca estándar de C ++ de Microsoft, Stephan T. Lavavej, ha indicado que esto se ha corregido en VS2015 mediante el uso de QueryPerformanceCounter() .


Tal vez la implementación no implementa el temporizador de mayor resolución?

Parece que estás usando Windows (mencionas C #) así que si tienes un temporizador y de hecho estás usando Windows puedes usar QueryPerformanceFrequency y QueryPerformanceCounter .


Voy a adivinar que estás usando VS2012; Si no, ignore esta respuesta. Tipo de alta definición de VS2012 typedef ''s clock_clock. Lamentablemente, esto significa que tiene una precisión horrible (alrededor de 1 ms). Escribí un mejor reloj de alta resolución que usa QueryPerformanceCounter para usar en VS2012 ...

HighResClock.h:

struct HighResClock { typedef long long rep; typedef std::nano period; typedef std::chrono::duration<rep, period> duration; typedef std::chrono::time_point<HighResClock> 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<rep>(period::den) / g_Frequency)); }

(Dejé fuera un assert y #ifs para ver si se compila en 2012 desde el código anterior)

Puede usar este reloj en cualquier lugar y de la misma manera que los relojes estándar.