Compartir a través de


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. En el caso del 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 Hora Universal Coordinada (UTC), para uso en mediciones de alta resolución de la hora 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 equipo y red. Estas operaciones de medición de rendimiento incluyen el cálculo del tiempo de respuesta, el rendimiento y la latencia, así como la generación de perfiles de ejecución de código. Cada una de estas operaciones implica una medida de las actividades que se producen durante un intervalo de tiempo definido por un inicio y un evento de finalización que puede ser independiente de cualquier referencia de hora del 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 los eventos de marca de 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 pueden encontrarse 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. Los sistemas con firmware defectuoso que ejecutan estas versiones de Windows podrían no proporcionar la misma lectura de QPC en diferentes núcleos si usaban el TSC como base para QPC.

Windows Vista y Windows Server 2008

Todos los equipos que se enviaron 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 mayor latencia de acceso 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 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 por procesador de alta resolución 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 utilizan los TSC como base de QPC en sistemas con un solo dominio de reloj, donde el sistema operativo (o el hipervisor) puede sincronizar de manera estrecha 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 ninguna 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 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 considerablemente para adaptarse mejor a sistemas grandes con muchos procesadores. Además, se ha agregado compatibilidad con la nueva API de hora exacta del día, que permite adquirir marcas de tiempo precisas del reloj del sistema operativo. Para obtener más información, consulta GetSystemTimePreciseAsFileTime. En dispositivos Windows RT y Windows 11 y Windows 10 con 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 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 hora externa, elija QueryPerformanceCounter, KeQueryPerformanceCounter o KeQueryInterruptTimePrecise. Cuando necesite marcas de tiempo sincronizadas con 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 TSC como la base de QPC, por ejemplo, por las razones explicadas en Información del temporizador de hardware, adquirir marcas de tiempo de alta resolución puede resultar significativamente más costoso que adquirir marcas de tiempo con menor resolución. 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 con UTC, use GetSystemTimeAsFileTime o KeQuerySystemTime. Si se necesita una resolución más alta, 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 una ordenación ambigua. Si las marcas de tiempo se toman del mismo subproceso, esta incertidumbre de ± 1 tic no se aplica. 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 dominios de varios relojes que no están sincronizados en hardware, Windows determina que el TSC no se puede usar con fines 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 de varios relojes 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.

Virtualization

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 del hipervisor versión 1.0 y exponen la mejora del tiempo de referencia pueden ofrecer una sobrecarga considerablemente menor. Para obtener más información sobre las interfaces e iluminaciones del hipervisor, consulte Especificaciones del hipervisor.

Uso directo de TSC

Desaconsejamos encarecidamente usar la instrucción del procesador RDTSC o RDTSCP para consultar directamente el TSC, porque no obtendrás resultados confiables en algunas versiones de Windows, durante migraciones en vivo de máquinas virtuales y en sistemas de hardware sin TSC invariantes 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 obtener marcas de tiempo

Los distintos ejemplos de código de estas secciones muestran cómo obtener 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 puede 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 RDTSC/RDTSCP?

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

¿Cuál es la relación de QPC con una época de tiempo 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 marcas de tiempo de día 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 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, sistemas de varios núcleos y sistemas con hyper-threading?

Sí.

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

No es necesario realizar estas comprobaciones.

¿Qué procesadores tienen TSCs 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 en relación con las características del 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 plataformas de hardware de Windows RT?

Sí.

¿Con qué frecuencia se reinicia QPC?

No menos de 100 años desde el arranque más reciente del sistema, y potencialmente más largo dependiendo del temporizador de hardware subyacente utilizado. Para la mayoría de las aplicaciones, el efecto de desplazamiento 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 intervalo de tiempo va de 10 ciclos de CPU a 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 de cálculo por llamada es mayor que el TSC, y suele estar 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 (sin disminuir)?

Sí. QPC no da marcha atrás.

¿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 un orden ambiguo 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 double o float?

Hay varias cosas 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 (doble) 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 de enteros.

Como principio general, retrase estos cálculos y conversiones tanto como sea posible para evitar la acumulación de los errores introducidos.

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

Una hora de fichero es un valor de 64 bits que representa el número de intervalos de 100 nanosegundos que han transcurrido desde la medianoche del 1 de enero de 1601 según la Hora Universal Coordinada (UTC). Los tiempos de archivo son utilizados por las llamadas API de Win32 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 relació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 devuelta por QPC es un entero con signo?

Los cálculos que implican marcas de tiempo de QPC pueden implicar la resta. Mediante el uso de un valor con signo, puede gestionar 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, siempre que pase parámetros válidos a las funciones.

¿Es necesario establecer la afinidad de subproceso en un único 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. La realización de este escenario podría afectar negativamente al rendimiento de la aplicación al restringir el procesamiento a un núcleo o mediante la creación de un cuello de botella en un único núcleo si varios subprocesos establecen su afinidad en el mismo núcleo al llamar a QueryPerformanceCounter.

Características de 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 forma en que se sincronizan con una referencia de tiempo 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 tiempo externa. Cuando se usa QPC para las mediciones de intervalo de tiempo, normalmente se obtiene una mayor 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 medidas de intervalo de tiempo a corto plazo.

Resolución, precisión, exactitud y estabilidad

QPC usa un contador de hardware como base. Los temporizadores de hardware constan de tres partes: un generador de ticks, un contador que cuenta los ticks y un método para obtener 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 ticks se denomina frecuencia y se expresa en Hertz (Hz). El recíproco de la frecuencia se denomina período o intervalo de tic y se expresa en una unidad de tiempo adecuada del Sistema Internacional de Unidades (SI) (por ejemplo, segundo, milisegundo, microsegundo o nanosegundo).

intervalo de tiempo

La resolución del temporizador es igual al intervalo. 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 medidas típicas de 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 tick usando un temporizador con una resolución de una unidad de tiempo.

incertidumbre de tic

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 ticks de hardware. Por ejemplo, en algunas versiones anteriores de Windows, QueryPerformanceFrequency devuelve la frecuencia de TSC dividida entre 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 ticks que se han producido desde que se inició el sistema operativo Windows, incluyendo el tiempo en que la máquina estaba en estado de suspensión, hibernación o espera conectada.

Estos ejemplos muestran cómo calcular el intervalo de tic y la resolución, y cómo convertir la cuenta 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 de QPC en esta máquina? El intervalo de ticks, o periodo, es el recíproco 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 inferiores a 320 nanosegundos no se pueden medir en esta máquina.

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

Intervalo de tic = 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 producen 1,6 microsegundos.

TiempoTranscurrido = Ticks * IntervaloDeTicks

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

Se tarda tiempo en acceder (leer) al contador de tics a través del software, y este tiempo de acceso puede reducir la precisión de la medición 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 el mayor de la resolución y el tiempo de acceso.

Precision = MAX [Resolución, TiempoDeAcceso]

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.

Precisión = 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 la mitad, al principio o al final de la llamada.

Por el contrario, considere el ejemplo siguiente en el que el tiempo de acceso de QPC es 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.

precisión de qpc

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á la más alta de las dos.

En esta tabla se 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 nominal del reloj Resolución del reloj Hora de acceso (típica) Precisión
PC RTC 64 Hz 15,625 milisegundos N/A N/A
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á conocimientos sobre las funcionalidades y limitaciones de QPC.

El generador de pulsos 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 utiliza para generar los pulsos 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 pulsos 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 lo 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 lo que realmente son.

En el caso de las mediciones típicas de intervalo de tiempo durante corta duración (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 osciladora se vuelve importante, especialmente durante intervalos de tiempo prolongados o cuando desea comparar las medidas tomadas en diferentes máquinas. El resto de esta sección explora 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 se especifica por 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 máximo de frecuencia 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 por millón en 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, funcionaría rápidamente y estimarí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 a la frecuencia +/- 10 PPM
1 microsegundo ± 10 picosegundos (10-12)
1 milisegundos ± 10 nanosegundos (10-9)
1 segundo ± 10 microsegundos
1 minuto ± 60 microsegundos
1 hora ± 36 milisegundos
1 día ± 0,86 segundos
1 semana ± 6,08 segundos

 

En la tabla anterior se muestra que, durante 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 ordenadores personales y servidores suelen fabricarse con una tolerancia de frecuencia de ± 30 a 50 partes por millón, y rara vez, los cristales pueden desviarse 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 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 microsegundo 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 medimos un intervalo de tiempo de 24 horas, nuestra medición sería de 4,3 segundos demasiado corta (23:59:55.700000 medido 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 está controlado por un oscilador de cristal y ha especificado la frecuencia de 3 GHz. Esto significa que la resolución sería de 1/3.000.000.000 o aproximadamente 333 picosegundos. Supongamos que el cristal usado para controlar el reloj del procesador tiene una tolerancia de frecuencia de ±50 ppm y en realidad es +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.0000000000 reales).

Segundos en un día = 86400

Error de desviación 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 adelanta 4,3 segundos y el otro atrasa 4,3 segundos, 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 es cada vez más importante al medir intervalos de tiempo largos y al comparar las medidas entre diferentes 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 pulsos en los ordenadores mostrarán pequeños cambios en la frecuencia en 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 , lo que proporciona un tiempo de acceso muy bajo y un 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 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 hora alternativo para QPC en este caso, lo que evita el problema de portabilidad).
  • Algunos procesadores pueden variar la frecuencia del reloj de TSC o detener el avance del registro TSC, lo que hace que el TSC no sea adecuado para fines de cronometraje 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 el hipervisor borre el bit de característica invariable del TSC en el CPUID si este tipo de migración en vivo es posible para un huésped).
  • 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 grandes, es posible que no pueda sincronizar los relojes del procesador con el mismo valor aunque el procesador tenga un TSC invariable. (Windows detectará esto automáticamente y seleccionará un origen de hora alternativo para QPC).
  • Algunos procesadores ejecutarán instrucciones fuera de orden. 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 mediante otra referencia de tiempo.

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

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 para toda la plataforma, aunque un sistema puede tener varios HPET. La compatibilidad con HPET ha estado en Windows desde Windows Vista, y la certificación de logotipo de hardware de Windows 7 y Windows 8 requiere compatibilidad con HPET en la plataforma de hardware.

Contador del sistema de temporizador genérico (Arm)

Las plataformas basadas en Arm no tienen relojes TSC, HPET o PM como en las 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 contadores del sistema (por ejemplo, CNTVCT_EL0). El contador del sistema de temporizador genérico es un origen de tiempo de toda la plataforma de frecuencia fija. Comienza en cero al iniciarse y aumenta a una velocidad alta. En Armv8.6 o superior, se define como exactamente 1 GHz, pero debe determinarse leyendo el registro de frecuencia del reloj que se establece mediante el firmware de arranque anticipado. Para obtener más información, consulte el capítulo "El temporizador genérico en estado AArch64" en el "Manual de referencia de la arquitectura Arm para arquitectura A-profile" (DDI 0487).

Contador de Ciclos (ARM)

Las plataformas basadas en Arm proporcionan un Registro del Contador de Ciclos del Monitor 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.