Adquisición de marcas de tiempo de alta resolución

Windows proporciona API que puede usar para adquirir marcas de tiempo de alta resolución o medir intervalos de tiempo. La API principal para código nativo es QueryPerformanceCounter (QPC). En el caso de los controladores de dispositivos, la API en modo kernel es KeQueryPerformanceCounter. Para el código administrado, la clase System.Diagnostics.Stopwatch usa QPC como base de tiempo precisa.

QPC es independiente de y no se sincroniza con ninguna referencia de hora externa. Para recuperar marcas de tiempo que se pueden sincronizar con una referencia de hora externa, como la hora universal coordinada (UTC) para su uso en medidas de hora de alta resolución del día, use GetSystemTimePreciseAsFileTime.

Las marcas de tiempo y las medidas de intervalo de tiempo son una parte integral de las medidas de rendimiento de la red y del equipo. Estas operaciones de medición de rendimiento incluyen el cálculo del tiempo de respuesta, el rendimiento y la latencia, así como la ejecución del código de generación de perfiles. Cada una de estas operaciones implica una medida de las actividades que se producen durante un intervalo de tiempo definido por un evento de inicio y finalización que puede ser independiente de cualquier referencia de hora de día externa.

QPC suele ser el mejor método para usar en eventos de marca de tiempo y medir intervalos de tiempo pequeños que se producen en el mismo sistema o máquina virtual. Considere la posibilidad de usar GetSystemTimePreciseAsFileTime cuando desee marcar el tiempo en varias máquinas, siempre que cada máquina participe en un esquema de sincronización de hora, como el Protocolo de tiempo de red (NTP). QPC le ayuda a evitar dificultades que se pueden encontrar con otros enfoques de medición de tiempo, como leer directamente el contador de marca de tiempo (TSC) del procesador.

Compatibilidad con QPC en versiones de Windows

QPC se introdujo en Windows 2000 y Windows XP y ha evolucionado para aprovechar las mejoras en la plataforma de hardware y los procesadores. Aquí se describen las características de QPC en diferentes versiones de Windows para ayudarle a mantener el software que se ejecuta en esas versiones de Windows.

Windows XP y Windows 2000

QPC está disponible en Windows XP y Windows 2000 y funciona bien en la mayoría de los sistemas. Sin embargo, el BIOS de algunos sistemas de hardware no indicó correctamente las características de CPU de hardware (un TSC no invariable) y algunos sistemas de varios núcleos o de varios procesadores que usaban procesadores con TSC que no se podían sincronizar entre núcleos. Es posible que los sistemas con firmware defectuoso que ejecuten estas versiones de Windows no proporcionen la misma lectura de QPC en núcleos diferentes si usaron el TSC como base para QPC.

Windows Vista y Windows Server 2008

Todos los equipos que se incluyen con Windows Vista y Windows Server 2008 usaron un contador de plataforma (temporizador de eventos de alta precisión (HPET)) o el temporizador de administración de energía ACPI (temporizador pm) como base para QPC. Estos temporizadores de plataforma tienen una latencia de acceso mayor que el TSC y se comparten entre varios procesadores. Esto limita la escalabilidad de QPC si se llama simultáneamente desde varios procesadores.

Windows 7 y Windows Server 2008 R2

La mayoría de los equipos con Windows 7 y Windows Server 2008 R2 tienen procesadores con TSC de velocidad constante y usan estos contadores como base para QPC. Los TSC son contadores de hardware de alta resolución por procesador a los que se puede acceder con una latencia y sobrecarga muy baja (en el orden de 10 o 100 ciclos de máquina, según el tipo de procesador). Windows 7 y Windows Server 2008 R2 usan TSC como base de QPC en sistemas de dominio de un solo reloj en los que el sistema operativo (o el hipervisor) es capaz de sincronizar estrechamente los TSC individuales en todos los procesadores durante la inicialización del sistema. En estos sistemas, el costo de leer el contador de rendimiento es significativamente menor en comparación con los sistemas que usan un contador de plataforma. Además, no hay sobrecarga adicional para las llamadas simultáneas y las consultas en modo de usuario a menudo omiten las llamadas del sistema, lo que reduce aún más la sobrecarga. En los sistemas en los que el TSC no es adecuado para el mantenimiento del tiempo, Windows selecciona automáticamente un contador de plataforma (ya sea el temporizador HPET o el temporizador ACPI PM) como base para QPC.

Windows 8, Windows 8.1, Windows Server 2012 y Windows Server 2012 R2

Windows 8, Windows 8.1, Windows Server 2012 y Windows Server 2012 R2 usan TSC como base para el contador de rendimiento. El algoritmo de sincronización de TSC se ha mejorado significativamente para adaptarse mejor a sistemas grandes con muchos procesadores. Además, se ha agregado compatibilidad con la nueva API de hora de día precisa, lo que permite adquirir marcas de tiempo de reloj precisas del sistema operativo. Para obtener más información, consulta GetSystemTimePreciseAsFileTime. En Windows RT y Windows 11 y Windows 10 dispositivos que usan procesadores Arm, el contador de rendimiento se basa en un contador de plataforma propietario o en el contador del sistema proporcionado por el temporizador genérico de Arm si la plataforma está tan equipada.

Guía para adquirir marcas de tiempo

Windows tiene y seguirá invirtiendo en proporcionar un contador de rendimiento confiable y eficaz. Cuando necesite marcas de tiempo con una resolución de 1 microsegundos o superior y no necesite que las marcas de tiempo se sincronicen con una referencia de tiempo externa, elija QueryPerformanceCounter, KeQueryPerformanceCounter o KeQueryInterruptTimePrecise. Cuando necesite marcas de tiempo sincronizadas por UTC con una resolución de 1 microsegundos o superior, elija GetSystemTimePreciseAsFileTime o KeQuerySystemTimePrecise.

En un número relativamente pequeño de plataformas que no pueden usar el registro de TSC como base de QPC , por ejemplo, por motivos explicados en Información del temporizador de hardware, la adquisición de marcas de tiempo de alta resolución puede ser significativamente más costosa que adquirir marcas de tiempo con una resolución inferior. Si la resolución de 10 a 16 milisegundos es suficiente, puede usar GetTickCount64, QueryInterruptTime, QueryUnbiasedInterruptTime, KeQueryInterruptTime o KeQueryUnbiasedInterruptTime para obtener marcas de tiempo que no están sincronizadas con una referencia de tiempo externa. Para las marcas de tiempo sincronizadas por UTC, use GetSystemTimeAsFileTime o KeQuerySystemTime. Si se necesita una resolución superior, puede usar QueryInterruptTimePrecise, QueryUnbiasedInterruptTimePrecise o KeQueryInterruptTimePrecise para obtener marcas de tiempo en su lugar.

En general, los resultados del contador de rendimiento son coherentes en todos los procesadores de sistemas de varios núcleos y de varios procesadores, incluso cuando se miden en diferentes subprocesos o procesos. Estas son algunas excepciones a esta regla:

  • Los sistemas operativos Anteriores a Windows Vista que se ejecutan en determinados procesadores podrían infringir esta coherencia debido a una de estas razones:

    • Los procesadores de hardware tienen un TSC no invariable y el BIOS no indica esta condición correctamente.
    • El algoritmo de sincronización de TSC que se usó no era adecuado para sistemas con un gran número de procesadores.
  • Al comparar los resultados del contador de rendimiento adquiridos a partir de diferentes subprocesos, tenga en cuenta los valores que difieren en ± 1 tic para tener un orden ambiguo. Si las marcas de tiempo se toman del mismo subproceso, no se aplica esta incertidumbre de 1 tic ±. En este contexto, el término tick hace referencia a un período de tiempo igual a 1 ÷ (la frecuencia del contador de rendimiento obtenido de QueryPerformanceFrequency).

Cuando se usa el contador de rendimiento en sistemas de servidores grandes con varios dominios de reloj que no están sincronizados en hardware, Windows determina que el TSC no se puede usar con fines de control de tiempo y selecciona un contador de plataforma como base para QPC. Aunque este escenario sigue produciendo marcas de tiempo confiables, la latencia de acceso y la escalabilidad se ven afectadas negativamente. Por lo tanto, como se indicó anteriormente en las instrucciones de uso anteriores, use solo las API que proporcionan 1 microsegundos o una mejor resolución cuando sea necesaria dicha resolución. El TSC se usa como base para QPC en sistemas de dominio multiproceso que incluyen la sincronización de hardware de todos los dominios de reloj del procesador, ya que esto hace que funcionen de forma eficaz como un sistema de dominio de reloj único.

La frecuencia del contador de rendimiento se fija en el arranque del sistema y es coherente en todos los procesadores, por lo que solo necesita consultar la frecuencia de QueryPerformanceFrequency a medida que se inicializa la aplicación y, a continuación, almacenar en caché el resultado.

Virtualización

Se espera que el contador de rendimiento funcione de forma confiable en todas las máquinas virtuales invitadas que se ejecutan en hipervisores implementados correctamente. Sin embargo, los hipervisores que cumplen con la interfaz de hipervisor versión 1.0 y exponen la iluminación del tiempo de referencia pueden ofrecer una sobrecarga considerablemente menor. Para obtener más información sobre las interfaces del hipervisor y las iluminaciones, consulte Especificaciones del hipervisor.

Uso directo de TSC

No recomendamos encarecidamente usar la instrucción de procesador RDTSC o RDTSCP para consultar directamente el TSC porque no obtendrá resultados confiables en algunas versiones de Windows, en migraciones en vivo de máquinas virtuales y en sistemas de hardware sin TSC invariables o estrechamente sincronizados. En su lugar, le recomendamos que use QPC para aprovechar la abstracción, la coherencia y la portabilidad que ofrece.

Ejemplos para adquirir marcas de tiempo

Los distintos ejemplos de código de estas secciones muestran cómo adquirir marcas de tiempo.

Uso de QPC en código nativo

En este ejemplo se muestra cómo usar QPC en código nativo de C y C++.

LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
LARGE_INTEGER Frequency;

QueryPerformanceFrequency(&Frequency); 
QueryPerformanceCounter(&StartingTime);

// Activity to be timed

QueryPerformanceCounter(&EndingTime);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;


//
// We now have the elapsed number of ticks, along with the
// number of ticks-per-second. We use these values
// to convert to the number of elapsed microseconds.
// To guard against loss-of-precision, we convert
// to microseconds *before* dividing by ticks-per-second.
//

ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;

Adquisición de marcas de tiempo de alta resolución a partir de código administrado

En este ejemplo se muestra cómo usar la clase System.Diagnostics.Stopwatch de código administrado.

using System.Diagnostics;

long StartingTime = Stopwatch.GetTimestamp();

// Activity to be timed

long EndingTime  = Stopwatch.GetTimestamp();
long ElapsedTime = EndingTime - StartingTime;

double ElapsedSeconds = ElapsedTime * (1.0 / Stopwatch.Frequency);

La clase System.Diagnostics.Stopwatch también proporciona varios métodos prácticos para realizar mediciones de intervalo de tiempo.

Uso de QPC desde el modo kernel

El kernel de Windows proporciona acceso en modo kernel al contador de rendimiento a través de KeQueryPerformanceCounter desde el que se pueden obtener el contador de rendimiento y la frecuencia de rendimiento. KeQueryPerformanceCounter solo está disponible en modo kernel y se proporciona para escritores de controladores de dispositivos y otros componentes en modo kernel.

En este ejemplo se muestra cómo usar KeQueryPerformanceCounter en modo kernel de C y C++.

LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
LARGE_INTEGER Frequency;

StartingTime = KeQueryPerformanceCounter(&Frequency);

// Activity to be timed

EndingTime = KeQueryPerformanceCounter(NULL);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;

Preguntas más frecuentes generales sobre QPC y TSC

Estas son las respuestas a las preguntas más frecuentes sobre QPC y TSC en general.

¿QueryPerformanceCounter() es el mismo que la función GetTickCount() o GetTickCount64() de Win32?

No. GetTickCount y GetTickCount64 no están relacionados con QPC. GetTickCount y GetTickCount64 devuelven el número de milisegundos desde que se inició el sistema.

¿Debo usar QPC o llamar directamente a las instrucciones de RDTSC/RDTSCP?

Para evitar problemas de portabilidad y falta de compatibilidad, le recomendamos encarecidamente que use QPC en lugar de usar el registro de TSC o las instrucciones del procesador RDTSC o RDTSCP .

¿Cuál es la relación de QPC con una época temporal externa? ¿Se puede sincronizar con una época externa como UTC?

QPC se basa en un contador de hardware que no se puede sincronizar con una referencia de hora externa, como UTC. Para las marcas de tiempo de hora precisas que se pueden sincronizar con una referencia UTC externa, use GetSystemTimePreciseAsFileTime.

¿QPC se ve afectado por el horario de verano, los segundos bisiestos, las zonas horarias o los cambios de hora del sistema realizados por el administrador?

No. QPC es completamente independiente de la hora del sistema y utc.

¿La precisión de QPC se ve afectada por los cambios de frecuencia del procesador causados por la administración de energía o la tecnología Turbo Boost?

No. Si el procesador tiene un TSC invariable, el QPC no se ve afectado por este tipo de cambios. Si el procesador no tiene un TSC invariable, QPC revertirá a un temporizador de hardware de plataforma que no se verá afectado por los cambios de frecuencia del procesador o la tecnología Turbo Boost.

¿QPC funciona de forma confiable en sistemas de varios procesadores, sistema de varios núcleos y sistemas con hyper-threading?

Sí.

Cómo determinar y validar que QPC funciona en mi máquina?

No es necesario realizar estas comprobaciones.

¿Qué procesadores tienen TSC no invariables? ¿Cómo puedo comprobar si mi sistema tiene un TSC no invariable?

No es necesario realizar esta comprobación usted mismo. Los sistemas operativos Windows realizan varias comprobaciones en la inicialización del sistema para determinar si el TSC es adecuado como base para QPC. Sin embargo, para fines de referencia, puede determinar si el procesador tiene un TSC invariable mediante uno de estos:

  • la utilidad Coreinfo.exe de Windows Sysinternals
  • comprobación de los valores devueltos por la instrucción CPUID relativa a las características de TSC
  • documentación del fabricante del procesador

A continuación se muestra la información de TSC-INVARIANT proporcionada por la utilidad sysinternals de Windows Coreinfo.exe (www.sysinternals.com). Un asterisco significa "True".

> Coreinfo.exe 

Coreinfo v3.2 - Dump information on system CPU and memory topology
Copyright (C) 2008-2012 Mark Russinovich
Sysinternals - www.sysinternals.com

 <unrelated text removed>

RDTSCP          * Supports RDTSCP instruction
TSC             * Supports RDTSC instruction
TSC-DEADLINE    - Local APIC supports one-shot deadline timer
TSC-INVARIANT   * TSC runs at constant rate

¿QPC funciona de forma confiable en Windows RT plataformas de hardware?

Sí.

¿Con qué frecuencia se revierte QPC?

No menos de 100 años a partir del arranque del sistema más reciente y potencialmente más largo en función del temporizador de hardware subyacente usado. Para la mayoría de las aplicaciones, la sustitución no es un problema.

¿Cuál es el costo computacional de llamar a QPC?

El costo de llamada computacional de QPC se determina principalmente por la plataforma de hardware subyacente. Si el registro de TSC se usa como base para QPC, el costo computacional se determina principalmente por cuánto tiempo tarda el procesador en procesar una instrucción RDTSC . Este tiempo oscila entre 10 ciclos de CPU y varios cientos de ciclos de CPU en función del procesador utilizado. Si no se puede usar el TSC, el sistema seleccionará una base de tiempo de hardware diferente. Dado que estas bases de tiempo se encuentran en la placa base (por ejemplo, en el puente sur pci o PCH), el costo computacional por llamada es mayor que el TSC, y con frecuencia se encuentra en las proximidades de 0,8 - 1,0 microsegundos dependiendo de la velocidad del procesador y otros factores de hardware. Este costo está dominado por el tiempo necesario para acceder al dispositivo de hardware en la placa base.

¿QPC requiere una transición del kernel (llamada al sistema)?

No se requiere una transición del kernel si el sistema puede usar el registro de TSC como base para QPC. Si el sistema debe usar una base de tiempo diferente, como el temporizador HPET o PM, se requiere una llamada del sistema.

¿Es el contador de rendimiento monotónico (no disminuye)?

Sí. QPC no retrocede.

¿Se puede usar el contador de rendimiento para ordenar eventos a tiempo?

Sí. Sin embargo, al comparar los resultados del contador de rendimiento adquiridos a partir de subprocesos diferentes, los valores que difieren en ± 1 tic tienen una ordenación ambigua como si tuvieran una marca de tiempo idéntica.

¿Qué precisión tiene el contador de rendimiento?

La respuesta depende de diversos factores. Para obtener más información, consulta Características de reloj de hardware de bajo nivel.

Preguntas más frecuentes sobre la programación con QPC y TSC

Estas son las respuestas a las preguntas más frecuentes sobre la programación con QPC y TSC.

Necesito convertir la salida de QPC en milisegundos. ¿Cómo puedo evitar la pérdida de precisión con la conversión a doble o flotante?

Hay varios aspectos que se deben tener en cuenta al realizar cálculos en contadores de rendimiento enteros:

  • La división de enteros perderá el resto. Esto puede provocar la pérdida de precisión en algunos casos.
  • La conversión entre enteros de 64 bits y punto flotante (double) puede provocar la pérdida de precisión porque la mantisa de punto flotante no puede representar todos los valores enteros posibles.
  • La multiplicación de enteros de 64 bits puede dar lugar a un desbordamiento entero.

Como principio general, retrase estos cálculos y conversiones siempre y cuando sea posible para evitar la composición de los errores introducidos.

¿Cómo puedo convertir QPC a 100 tics nanosegundos para poder agregarlo a un FILETIME?

Un tiempo de archivo es un valor de 64 bits que representa el número de intervalos de 100 nanosegundos que han transcurrido desde las 12:00 A.M. 1 de enero de 1601 Hora universal coordinada (UTC). Las llamadas API de Win32 usan las horas de archivo que devuelven la hora del día, como GetSystemTimeAsFileTime y GetSystemTimePreciseAsFileTime. Por el contrario, QueryPerformanceCounter devuelve valores que representan el tiempo en unidades de 1/(la frecuencia del contador de rendimiento obtenido de QueryPerformanceFrequency). La conversión entre los dos requiere calcular la proporción del intervalo QPC y los intervalos de 100 nanosegundos. Tenga cuidado de evitar perder precisión porque los valores pueden ser pequeños (0,0000001 / 0,000000340).

¿Por qué la marca de tiempo que se devuelve de QPC es un entero con signo?

Los cálculos que implican marcas de tiempo de QPC pueden implicar resta. Mediante el uso de un valor con signo, puede controlar los cálculos que podrían producir valores negativos.

¿Cómo puedo obtener marcas de tiempo de alta resolución del código administrado?

Llame al método Stopwatch.GetTimeStamp desde la clase System.Diagnostics.Stopwatch . Para obtener un ejemplo sobre cómo usar Stopwatch.GetTimeStamp, consulte Adquisición de marcas de tiempo de alta resolución a partir de código administrado.

En qué circunstancias devuelve QueryPerformanceFrequency FALSE o QueryPerformanceCounter devuelve cero?

Esto no se producirá en ningún sistema que ejecute Windows XP o posterior.

¿Es necesario establecer la afinidad de subproceso en un solo núcleo para usar QPC?

No. Para obtener más información, consulta Guía para adquirir marcas de tiempo. Este escenario no es necesario ni deseable. Realizar este escenario podría afectar negativamente al rendimiento de la aplicación restringiendo el procesamiento a un núcleo o creando un cuello de botella en un solo núcleo si varios subprocesos establecen su afinidad en el mismo núcleo al llamar a QueryPerformanceCounter.

Características del reloj de hardware de bajo nivel

En estas secciones se muestran características de reloj de hardware de bajo nivel.

Relojes absolutos y relojes de diferencia

Los relojes absolutos proporcionan lecturas precisas de la hora del día. Normalmente se basan en la hora universal coordinada (UTC) y, por lo tanto, su precisión depende en parte de la sincronización con una referencia de hora externa. Los relojes de diferencia miden los intervalos de tiempo y normalmente no se basan en una época de tiempo externa. QPC es un reloj de diferencia y no se sincroniza con una época o referencia de hora externa. Cuando se usa QPC para las mediciones de intervalo de tiempo, normalmente se obtiene una mejor precisión de la que obtendría mediante marcas de tiempo derivadas de un reloj absoluto. Esto se debe a que el proceso de sincronización de la hora de un reloj absoluto puede introducir cambios de fase y frecuencia que aumentan la incertidumbre de las mediciones de intervalos de tiempo a corto plazo.

Resolución, precisión, precisión y estabilidad

QPC usa un contador de hardware como base. Los temporizadores de hardware constan de tres partes: un generador de tics, un contador que cuenta los tics y un medio para recuperar el valor del contador. Las características de estos tres componentes determinan la resolución, precisión, precisión y estabilidad de QPC.

Si un generador de hardware proporciona tics a una velocidad constante, los intervalos de tiempo se pueden medir simplemente contando estos tics. La velocidad a la que se generan los tics se denomina frecuencia y se expresa en Hertz (Hz). La recíproca de la frecuencia se denomina período o intervalo de graduación y se expresa en una unidad de tiempo del Sistema Internacional de Unidades (SI) adecuada (por ejemplo, segundo, milisegundos, microsegundos o nanosegundos).

intervalo de tiempo

La resolución del temporizador es igual al período. La resolución determina la capacidad de distinguir entre dos marcas de tiempo y coloca un límite inferior en los intervalos de tiempo más pequeños que se pueden medir. Esto a veces se denomina resolución de tics.

La medición digital del tiempo introduce una incertidumbre de medición de ± 1 tic porque el contador digital avanza en pasos discretos, mientras que el tiempo avanza continuamente. Esta incertidumbre se denomina error de cuantificación. En el caso de las mediciones típicas del intervalo de tiempo, este efecto se puede omitir a menudo porque el error de cuantificación es mucho menor que el intervalo de tiempo que se mide.

medición de tiempo digital

Sin embargo, si el período que se mide es pequeño y se aproxima a la resolución del temporizador, deberá tener en cuenta este error de cuantificación. El tamaño del error introducido es el de un período de reloj.

En los dos diagramas siguientes se muestra el impacto de la incertidumbre de ± 1 tic mediante un temporizador con una resolución de 1 unidad de tiempo.

incertidumbre de tics

QueryPerformanceFrequency devuelve la frecuencia de QPC y el período y la resolución son iguales al mutuo de este valor. La frecuencia del contador de rendimiento que devuelve QueryPerformanceFrequency se determina durante la inicialización del sistema y no cambia mientras se ejecuta el sistema.

Nota

A menudo QueryPerformanceFrequency no devuelve la frecuencia real del generador de tics de hardware. Por ejemplo, en algunas versiones anteriores de Windows, QueryPerformanceFrequency devuelve la frecuencia de TSC dividida por 1024; y cuando se ejecuta con un hipervisor que implementa la interfaz de hipervisor versión 1.0 (o siempre en algunas versiones más recientes de Windows), la frecuencia del contador de rendimiento se fija a 10 MHz. Como resultado, no suponga que QueryPerformanceFrequency devolverá un valor derivado de la frecuencia de hardware.

 

QueryPerformanceCounter lee el contador de rendimiento y devuelve el número total de tics que se han producido desde que se inició el sistema operativo Windows, incluida la hora en que la máquina estaba en estado de suspensión, como espera, hibernación o espera conectada.

En estos ejemplos se muestra cómo calcular el intervalo de graduación y la resolución y cómo convertir el recuento de tics en un valor de tiempo.

Ejemplo 1

QueryPerformanceFrequency devuelve el valor 3.125.000 en un equipo determinado. ¿Cuál es el intervalo de graduación y la resolución de las medidas QPC en esta máquina? El intervalo de graduación, o período, es el mutuo de 3.125.000, que es 0.000000320 (320 nanosegundos). Por lo tanto, cada tic representa el paso de 320 nanosegundos. Los intervalos de tiempo menores que 320 nanosegundos no se pueden medir en esta máquina.

Intervalo de graduación = 1/(Frecuencia de rendimiento)

Intervalo de graduación = 1/3,125 000 = 320 ns

Ejemplo 2

En el mismo equipo que el ejemplo anterior, la diferencia de los valores devueltos de dos llamadas sucesivas a QPC es 5. ¿Cuánto tiempo ha transcurrido entre las dos llamadas? 5 tics multiplicados por 320 nanosegundos produce 1,6 microsegundos.

ElapsedTime = Ticks * Tick Interval

ElapsedTime = 5 * 320 ns = 1,6 μs

Se tarda tiempo en acceder (leer) al contador de tics desde el software, y este tiempo de acceso puede reducir la precisión de la medida de tiempo. Esto se debe a que el tiempo de intervalo mínimo (el intervalo de tiempo más pequeño que se puede medir) es mayor de la resolución y el tiempo de acceso.

Precision = MAX [ Resolution, AccessTime]

Por ejemplo, considere un temporizador de hardware hipotético con una resolución de 100 nanosegundos y un tiempo de acceso de 800 nanosegundos. Esto puede ser el caso si se usó el temporizador de la plataforma en lugar del registro de TSC como base de QPC. Por lo tanto, la precisión sería 800 nanosegundos no 100 nanosegundos, como se muestra en este cálculo.

Precision = MAX [800 ns,100 ns] = 800 ns

Estas dos figuras representan este efecto.

Tiempo de acceso de qpc

Si el tiempo de acceso es mayor que la resolución, no intente mejorar la precisión adivinando. En otras palabras, es un error suponer que la marca de tiempo se toma precisamente en el medio, o al principio o al final de la llamada.

Por el contrario, considere el siguiente ejemplo en el que el tiempo de acceso de QPC es de solo 20 nanosegundos y la resolución del reloj de hardware es de 100 nanosegundos. Esto podría ser el caso si el registro de TSC se usó como base para QPC. Aquí la precisión está limitada por la resolución del reloj.

qpc precision

En la práctica, puede encontrar orígenes de tiempo para los que el tiempo necesario para leer el contador es mayor o menor que la resolución. En cualquier caso, la precisión será mayor de las dos.

Esta tabla proporciona información sobre la resolución aproximada, el tiempo de acceso y la precisión de una variedad de relojes. Tenga en cuenta que algunos de los valores variarán con diferentes procesadores, plataformas de hardware y velocidades de procesador.

Origen del reloj Frecuencia de reloj nominal Resolución del reloj Tiempo de acceso (típico) Precision
PC RTC 64 Hz 15,625 milisegundos N/D N/D
Contador de rendimiento de consultas mediante TSC con un reloj de procesador de 3 GHz 3 MHz 333 nanosegundos 30 nanosegundos 333 nanosegundos
Instrucción de máquina RDTSC en un sistema con un tiempo de ciclo de 3 GHz 3 GHz 333 picoseconds 30 nanosegundos 30 nanosegundos

 

Dado que QPC usa un contador de hardware, cuando comprende algunas características básicas de los contadores de hardware, obtendrá información sobre las funcionalidades y limitaciones de QPC.

El generador de tics de hardware más usado es un oscilador de cristal. El cristal es una pequeña pieza de cuarzo u otro material cerámico que exhibe características piezoeléctricas que proporcionan una referencia de frecuencia económica con excelente estabilidad y precisión. Esta frecuencia se usa para generar los tics contados por el reloj.

La precisión de un temporizador hace referencia al grado de conformidad con un valor verdadero o estándar. Esto depende principalmente de la capacidad del oscilador de cristal para proporcionar tics a la frecuencia especificada. Si la frecuencia de oscilación es demasiado alta, el reloj se "ejecutará rápido" y los intervalos medidos aparecerán más largos de los que realmente son; y si la frecuencia es demasiado baja, el reloj se "ejecutará lentamente" y los intervalos medidos aparecerán más cortos de los que realmente son.

Para las mediciones típicas de intervalo de tiempo durante una duración corta (por ejemplo, medidas de tiempo de respuesta, medidas de latencia de red, etc.), la precisión del oscilador de hardware suele ser suficiente. Sin embargo, para algunas mediciones, la precisión de la frecuencia de oscilador es importante, especialmente para intervalos de tiempo largos o cuando desea comparar las medidas tomadas en diferentes máquinas. En el resto de esta sección se exploran los efectos de la precisión del oscilador.

La frecuencia de oscilación de los cristales se establece durante el proceso de fabricación y la especifica el fabricante en términos de una frecuencia especificada más o menos una tolerancia de fabricación expresada en "partes por millón" (ppm), denominada desplazamiento de frecuencia máxima. Un cristal con una frecuencia especificada de 1.000.000 Hz y un desplazamiento de frecuencia máximo de ± 10 ppm estaría dentro de los límites de especificación si su frecuencia real estuviera entre 999.990 Hz y 1.000.010 Hz.

Al sustituir las partes de frase por millón con microsegundos por segundo, podemos aplicar este error de desplazamiento de frecuencia a las mediciones de intervalo de tiempo. Un oscilador con un desplazamiento + 10 ppm tendría un error de 10 microsegundos por segundo. En consecuencia, al medir un intervalo de 1 segundo, se ejecutaría rápido y mediría un intervalo de 1 segundo como 0,999990 segundos.

Una referencia conveniente es que un error de frecuencia de 100 ppm provoca un error de 8,64 segundos después de 24 horas. En esta tabla se presenta la incertidumbre de medición debido al error acumulado durante intervalos de tiempo más largos.

Duración del intervalo de tiempo Incertidumbre de medición debido a un error acumulado con tolerancia de frecuencia +/- 10 PPM
1 microsegundos ± 10 picosegundos (10-12)
1 milisegundo ± 10 nanosegundos (10-9)
1 segundo ± 10 microsegundos
1 hora ± 60 microsegundos
1 día ± 0,86 segundos
1 semana ± 6,08 segundos

 

En la tabla anterior se muestra que para intervalos de tiempo pequeños, a menudo se puede omitir el error de desplazamiento de frecuencia. Sin embargo, durante largos intervalos de tiempo, incluso un desplazamiento de frecuencia pequeño puede dar lugar a una incertidumbre de medición sustancial.

Los osciladores de cristal que se utilizan en equipos y servidores personales normalmente se fabrican con una tolerancia de frecuencia de ± de 30 a 50 partes por millón, y rara vez, los cristales pueden estar apagados hasta 500 ppm. Aunque los cristales con tolerancias de desplazamiento de frecuencia mucho más estrechas están disponibles, son más caros y, por lo tanto, no se usan en la mayoría de los equipos.

Para reducir los efectos adversos de este error de desplazamiento de frecuencia, las versiones recientes de Windows, especialmente Windows 8, usan varios temporizadores de hardware para detectar el desplazamiento de frecuencia y compensarlo en la medida de lo posible. Este proceso de calibración se realiza cuando se inicia Windows.

Como se muestra en los ejemplos siguientes, el error de desplazamiento de frecuencia de un reloj de hardware influye en la precisión factible y la resolución del reloj puede ser menos importante.

el error de desplazamiento de frecuencia influye en la precisión factible

Ejemplo 1

Supongamos que realiza mediciones de intervalo de tiempo mediante un oscilador de 1 MHz, que tiene una resolución de 1 microsegundos y un error de desplazamiento de frecuencia máximo de ±50 ppm. Ahora supongamos que el desplazamiento es exactamente +50 ppm. Esto significa que la frecuencia real sería de 1000 050 Hz. Si se mide un intervalo de tiempo de 24 horas, nuestra medición sería de 4,3 segundos demasiado corta (23:59:55.7000000 medida frente a 24:00:00.000000 reales).

Segundos en un día = 86400

Error de desplazamiento de frecuencia = 50 ppm = 0,00005

86 400 segundos * 0,00005 = 4,3 segundos

Ejemplo 2

Supongamos que el reloj TSC del procesador se controla mediante un oscilador de cristal y ha especificado la frecuencia de 3 GHz. Esto significa que la resolución sería 1/3.000.000.000 o aproximadamente 333 picoseconds. Supongamos que el cristal utilizado para controlar el reloj del procesador tiene una tolerancia de frecuencia de ±50 ppm y es realmente +50 ppm. A pesar de la impresionante resolución, una medición de intervalo de tiempo de 24 horas seguirá siendo de 4,3 segundos demasiado corta. (23:59:55.700000000000 medido frente a 24:00:00.00000000000 reales).

Segundos en un día = 86400

Error de desplazamiento de frecuencia = 50 ppm = 0,00005

86 400 segundos * 0,00005 = 4,3 segundos

Esto muestra que un reloj TSC de alta resolución no proporciona necesariamente medidas más precisas que un reloj de resolución inferior.

Ejemplo 3

Considere la posibilidad de usar dos equipos diferentes para medir el mismo intervalo de tiempo de 24 horas. Ambos equipos tienen un oscilador con un desplazamiento de frecuencia máximo de ± 50 ppm. ¿Qué distancia puede tener la medición del mismo intervalo de tiempo en estos dos sistemas? Como en los ejemplos anteriores, ± 50 ppm produce un error máximo de ± 4,3 segundos después de 24 horas. Si un sistema se ejecuta 4,3 segundos rápidamente y los otros 4,3 segundos lentos, el error máximo después de 24 horas podría ser de 8,6 segundos.

Segundos en un día = 86400

Error de desplazamiento de frecuencia = ±50 ppm = ±0,00005

±(86 400 segundos * 0,00005) = ±4,3 segundos

Desplazamiento máximo entre los dos sistemas = 8,6 segundos

En resumen, el error de desplazamiento de frecuencia se vuelve cada vez más importante al medir intervalos de tiempo largos y al comparar medidas entre distintos sistemas.

La estabilidad de un temporizador describe si la frecuencia de graduación cambia con el tiempo, por ejemplo, como resultado de los cambios de temperatura. Los cristales de cuarzo utilizados como generadores de tics en los ordenadores mostrarán pequeños cambios en la frecuencia como función de la temperatura. El error causado por el desfase térmico suele ser pequeño en comparación con el error de desplazamiento de frecuencia para los intervalos de temperatura comunes. Sin embargo, es posible que los diseñadores de software para equipos portátiles o equipos sujetos a grandes fluctuaciones de temperatura necesiten tener en cuenta este efecto.

Información del temporizador de hardware

Registro de TSC (x86 y x64)

Todos los procesadores Intel y AMD modernos contienen un registro TSC que es un registro de 64 bits que aumenta a una velocidad alta, normalmente igual al reloj del procesador. El valor de este contador se puede leer a través de las instrucciones de la máquina RDTSC o RDTSCP , proporcionando un tiempo de acceso muy bajo y costo computacional en el orden de decenas o cientos de ciclos de máquina, dependiendo del procesador.

Aunque el registro de TSC parece un mecanismo ideal de marca de tiempo, estas son las circunstancias en las que no puede funcionar de forma confiable con fines de mantenimiento de tiempo:

  • No todos los procesadores tienen registros TSC utilizables, por lo que el uso del registro de TSC en el software crea directamente un problema de portabilidad. (Windows seleccionará un origen de tiempo alternativo para QPC en este caso, lo que evita el problema de portabilidad).
  • Algunos procesadores pueden variar la frecuencia del reloj TSC o detener el avance del registro de TSC, lo que hace que el TSC no sea adecuado para fines de tiempo en estos procesadores. Se dice que estos procesadores tienen registros TSC no invariables. (Windows detectará esto automáticamente y seleccionará un origen de hora alternativo para QPC).
  • Incluso si un host de virtualización tiene un TSC utilizable, la migración en vivo de máquinas virtuales en ejecución cuando el host de virtualización de destino no tiene o utiliza el escalado de TSC asistido por hardware puede dar lugar a un cambio en la frecuencia de TSC que es visible para los invitados. (Se espera que si este tipo de migración en vivo es posible para un invitado, el hipervisor borra el bit de característica de TSC invariable en CPUID).
  • En sistemas multiprocesador o de varios núcleos, algunos procesadores y sistemas no pueden sincronizar los relojes de cada núcleo con el mismo valor. (Windows detectará esto automáticamente y seleccionará un origen de hora alternativo para QPC).
  • En algunos sistemas de varios procesadores de gran tamaño, es posible que no pueda sincronizar los relojes del procesador con el mismo valor incluso si el procesador tiene un TSC invariable. (Windows detectará esto automáticamente y seleccionará un origen de hora alternativo para QPC).
  • Algunos procesadores ejecutarán instrucciones desordenados. Esto puede dar lugar a recuentos de ciclos incorrectos cuando RDTSC se usa para las secuencias de instrucciones de tiempo, ya que la instrucción RDTSC se puede ejecutar en un momento diferente al especificado en el programa. La instrucción RDTSCP se ha introducido en algunos procesadores en respuesta a este problema.

Al igual que otros temporizadores, el TSC se basa en un oscilador de cristal cuya frecuencia exacta no se conoce de antemano y que tiene un error de desplazamiento de frecuencia. Por lo tanto, antes de que se pueda usar, debe calibrarse con otra referencia de control de tiempo.

Durante la inicialización del sistema, Windows comprueba si el TSC es adecuado para fines de tiempo y realiza la calibración de frecuencia y la sincronización de núcleos necesarias.

Reloj PM (x86 y x64)

El temporizador ACPI, también conocido como reloj PM, se agregó a la arquitectura del sistema para proporcionar marcas de tiempo confiables independientemente de la velocidad de los procesadores. Dado que este era el único objetivo de este temporizador, proporciona una marca de tiempo en un solo ciclo de reloj, pero no proporciona ninguna otra funcionalidad.

Temporizador HPET (x86 y x64)

Intel y Microsoft desarrollaron conjuntamente el temporizador de eventos de alta precisión (HPET) para satisfacer los requisitos de tiempo de las aplicaciones multimedia y otras aplicaciones sensibles al tiempo. A diferencia del TSC, que es un recurso por procesador, HPET es un recurso compartido en toda la plataforma, aunque un sistema puede tener varios HPET. La compatibilidad con HPET ha estado en Windows desde Windows Vista, y Windows 7 y Windows 8 certificación del logotipo de hardware requiere compatibilidad con HPET en la plataforma de hardware.

Contador del sistema de temporizador genérico (Arm)

Las plataformas basadas en Arm no tienen un reloj TSC, HPET o PM, ya que hay en plataformas basadas en Intel o AMD. En su lugar, los procesadores Arm proporcionan el temporizador genérico (a veces denominado temporizador de intervalo genérico o GIT) que contiene un registro de contador del sistema (por ejemplo, CNTVCT_EL0). El contador de sistema de temporizador genérico es un origen de tiempo de toda la plataforma de frecuencia fija. Comienza a cero en el inicio y aumenta a una velocidad alta. En Armv8.6 o superior, esto se define exactamente como 1 GHz, pero debe determinarse leyendo el registro de frecuencia del reloj que establece el firmware de arranque temprano. Para obtener más información, vea el capítulo "El temporizador genérico en estado AArch64" en "Arm Architecture Reference Manual for A-profile architecture" (DDI 0487).

Contador de ciclo (Arm)

Las plataformas basadas en Arm proporcionan un registro de contador de ciclo de monitores de rendimiento (por ejemplo, PMCCNTR_EL0). Este contador cuenta los ciclos de reloj del procesador. No es invariable y es posible que sus unidades no estén correlacionadas con tiempo real. No se recomienda usar este registro para obtener marcas de tiempo.