2010-05-13 27 views
6

Quiero calcular el rendimiento de una función en precisión de micro segundos en la plataforma de Windows.Cómo calcular el tiempo de una operación en microsegundos de precisión

Ahora Windows tiene una granulidad de milisegundos, así que ¿cómo puedo lograrlo?

Intenté seguir la muestra, pero no obteniendo los resultados correctos.

LARGE_INTEGER ticksPerSecond = {0}; 
LARGE_INTEGER tick_1 = {0}; 
LARGE_INTEGER tick_2 = {0}; 
double uSec = 1000000; 

// Get the frequency 
QueryPerformanceFrequency(&ticksPerSecond); 

//Calculate per uSec freq 
double uFreq = ticksPerSecond.QuadPart/uSec; 

// Get counter b4 start of op 
QueryPerformanceCounter(&tick_1); 

// The ope itself 
Sleep(10); 

// Get counter after opfinished 
QueryPerformanceCounter(&tick_2); 

// And now the op time in uSec 
double diff = (tick_2.QuadPart/uFreq) - (tick_1.QuadPart/uFreq); 
+3

¿Qué resultados * haces *? Tenga en cuenta que 'Sleep' no garantiza que duerma exactamente el tiempo especificado; usar, por ejemplo, 'Sleep (1000)' para dormir por un segundo, para que pueda verificar usted mismo si está haciendo más o menos lo correcto. – Thomas

+1

Cuenta silenciosamente para ti REALMENTE rápido. –

Respuesta

20

Ejecute la operación en un bucle un millón de veces más o menos y divida el resultado por ese número. De esa forma obtendrás el tiempo de ejecución promedio sobre tantas ejecuciones. Sincronizar una (o incluso cien) ejecuciones de una operación muy rápida es muy poco fiable, debido a la multitarea y otras cosas.

+0

Nota: Si la operación es lo suficientemente rápida, es posible que el ciclo en sí ocupe una parte del tiempo que le preocupa. Tenga esto en cuenta como una preocupación. – Brian

+0

el almacenamiento en caché tendrá efecto y acelerará la operación si lo recorre – PiNoYBoY82

+0

Looping 1M veces no es nada en comparación con los segundos que se ejecutará. Otra historia si quieres medir nanosegundos. Ah, y solo use un cronómetro ;-) – phkahler

0

Si usted está haciendo esto para fuera de línea de perfiles, de una manera muy sencilla es ejecutar la función de 1000 veces, medir al milisegundo más cercano y se dividen por 1000.

7
  • compilarlo
  • vistazo a la ensamblador de salida
  • contar el número de cada instrucción en su función
  • aplican los ciclos por instrucción de su procesador objetivo
  • terminan con un ciclo de recuento
  • se multiplica por la velocidad de reloj está ejecutando en
  • aplicar factores de escala arbitrarios para dar cuenta de los errores de caché y la rama erróneas predicciones lol

(hombre que soy por lo iba a conseguir abajo votado por esta respuesta)

+0

No bajoneo, solo notaré que la última línea (errores de caché y errores de predicción de ramas) es una prueba muy cuidadosa de los ciclos de CPU que ha obtenido hasta ahora: p –

+0

+ 1 gracioso. Sin embargo, si habla en serio, este es un consejo terrible. Como sarcasmo, es un muy buen ejemplo de por qué elegir la respuesta de Matti. –

+0

Downvoting? No por mí. Yo solía hacer eso, en realidad. Sin embargo, con la caché ahora no funciona realmente. Así que recomiendo el método run-it-a-million-times. –

3

No, probablemente obtenga un resultado preciso, QueryPerformanceCounter() funciona bien para temporizar intervalos cortos. Lo que está mal es su expectativa de la precisión de Sleep(). Tiene una resolución de 1 milisegundo, su precisión es mucho peor. No más de aproximadamente 15.625 milisegundos en la mayoría de las máquinas con Windows.

Para obtenerlo en cualquier lugar cercano a 1 milisegundo, primero tendrá que llamar al timeBeginPeriod(1). Eso probablemente mejorará el emparejamiento, ignorando la inestabilidad que obtendrá de Windows como sistema operativo multitarea.

+0

o usar seleccionar con un fd falso para obtener un "sueño" más preciso – PiNoYBoY82

0

Para obtener una resolución más fina de 1 ms, deberá consultar la documentación de su sistema operativo. Puede haber API para obtener una resolución de temporizador en resolución de microsegundos. Si es así, ejecute su aplicación muchas veces y tome los promedios.

+2

Hay. Se llama 'QueryPerformanceCounter'. Exactamente como lo menciona el OP. – Alan

-1

O puede utilizar gettimeofday() que le da una estructura timeval que es una marca de tiempo (hasta mu s)

+0

http://blogs.msdn.com/b/oldnewthing/archive/2005/09/02/459952.aspx – dan04

0

me gusta la respuesta de Matti Virkkunen. Verifique la hora, llame a la función una gran cantidad de veces, verifique la hora en que termina y divida por el número de veces que llamó a la función. Mencionó que podría estar apagado debido a las interrupciones del sistema operativo. Puede variar la cantidad de veces que realiza la llamada y ver la diferencia. ¿Puedes elevar la prioridad del proceso? ¿Puedes obtenerlo para todas las llamadas dentro de un único intervalo de tiempo del sistema operativo?

Dado que no sabe cuándo puede cambiar el sistema operativo, puede poner todo esto dentro de un bucle más grande para hacer toda la medición una gran cantidad de veces, y guardar el número más pequeño, ya que es el que tenía el menor número de interrupciones del sistema operativo. Todavía puede ser mayor que el tiempo real para que se ejecute la función, ya que aún puede contener algunas interrupciones del sistema operativo.

0

Sanjeet,

Parece (para mí) como que está haciendo esto exactamente correcto. QueryPerformanceCounter es una forma perfectamente buena de medir períodos cortos de tiempo con un alto grado de precisión. Si no está viendo el resultado que esperaba, es más probable porque el sueño no está durmiendo durante el tiempo que esperaba. Sin embargo, es probable que se mida correctamente.

Quiero volver a su pregunta original sobre cómo medir el tiempo en ventanas con precisión microsegunda. Como ya sabe, el contador de alto rendimiento (es decir, QueryPerformanceCounter) "marca" la frecuencia indicada por QueryPerformanceFrequency. Eso significa que se puede medir el tiempo con una precisión igual a:

1/frecuencia segundos

En mi máquina, QueryPerformanceFrequency informa 2.337.910 (cuentas/segundo). Eso significa que el QPC de mi computadora puede medir con precisión de 4.277e-7 segundos, o 0.427732 microsegundos. Eso significa que el menor tiempo que puedo medir es 0.427732 microsegundos. Esto, por supuesto, le da la precisión que originalmente pidió :) La frecuencia de su máquina debe ser similar, pero siempre puede hacer los cálculos y verificarlo.

Cuestiones relacionadas