segundo script microsegundo hora fecha linux time linux-kernel

script - ¿Cómo se obtiene el tiempo de microsegundo de linux gettimeofday() y cuál es su precisión?



microsegundo a segundo (2)

La hora del reloj de pared generalmente la proporcionan los sistemas RTC. Esto en su mayoría solo proporciona tiempos hasta el rango de milisegundos y, por lo general, tiene una granularidad de 10-20 milisegundos. Sin embargo, a menudo se reported que la resolución / granularidad de gettimeofday() está en el rango de pocos microsegundos. Supongo que la granularidad de microsegundos debe tomarse de una fuente diferente.

¿Cómo se logra la resolución / granularidad en microsegundos de gettimeofday ()?

Cuando la parte hasta el milisegundo se toma del RTC y los mircosegundos se toman de un hardware diferente, surge un problema con la puesta en fase de las dos fuentes. Las dos fuentes tienen que estar synchronized alguna manera.

¿Cómo se logra la sincronización / fase entre estas dos fuentes?

Editar: De lo que he leído en enlaces proporcionados por amdn, particularmente el siguiente enlace de Intel , agregaría una pregunta aquí:

¿ gettimeofday() proporciona resolución / granularidad en el régimen de microsegundos en absoluto?

Edit 2: Resumiendo la answer amdns con algunos resultados más de lectura:

Linux solo usa el reloj en tiempo real (RTC) en el momento del arranque para sincronizar con un contador de mayor resolución, ig el Timestampcounter (TSC). Después del arranque gettimeofday() devuelve un tiempo que está completamente basado en el valor de TSC y la frecuencia de este contador. El valor inicial para la frequency TSC se corrige / calibra mediante la comparación de la hora del sistema con una fuente de tiempo externa. El ajuste se realiza / configura mediante la función adjtimex() . El kernel opera un ciclo de fase bloqueada para asegurar que los resultados de tiempo sean monótonos y consistentes.

De esta forma, se puede afirmar que gettimeofday() tiene una resolución de microsegundos. Teniendo en cuenta que Timestampcounter más moderno se está ejecutando en el régimen de GHz, la resolución obtenible podría estar en el régimen de nanosegundos. Por lo tanto, este comentario significativo

/** 407 * do_gettimeofday - Returns the time of day in a timeval 408 * @tv: pointer to the timeval to be set 409 * 410 * NOTE: Users should be converted to using getnstimeofday() 411 */

se puede encontrar en Linux/kernel/time/timekeeping.c . Esto sugiere que posiblemente haya una función de resolución aún mayor disponible en un momento posterior. En este momento getnstimeofday() solo está disponible en el espacio del kernel.

Sin embargo, al revisar todo el código involucrado para entender esto correctamente, se muestran algunos comentarios sobre las incertidumbres. Es posible obtener una resolución de microsegundos. La función gettimeofday() puede incluso mostrar una granularidad en el régimen de microsegundos. Pero: hay datos severos sobre su precisión porque la drift de la frecuencia TSC no se puede corregir con precisión. También la complejidad del código que trata este asunto dentro de Linux es una pista para creer que de hecho es demasiado difícil hacerlo bien. Esto es particularmente, pero no únicamente, causado por la gran cantidad de plataformas de hardware en las que se supone que se ejecuta Linux.

Resultado: gettimeofday() devuelve el tiempo monotónico con una granularidad de microsegundos, pero el tiempo que proporciona casi nunca es de fase a one microsecond con ninguna otra fuente de tiempo.



¿Cómo se logra la resolución / granularidad en microsegundos de gettimeofday ()?

Linux se ejecuta en muchas plataformas de hardware diferentes, por lo que los detalles son diferentes. En una plataforma x86 moderna, Linux utiliza el Contador de sellos de tiempo , también conocido como el TSC , que es accionado por múltiples osciladores de cristal que funcionan a 133,33 MHz. El oscilador de cristal proporciona un reloj de referencia para el procesador y el procesador lo multiplica por un múltiplo; por ejemplo, en un procesador de 2.93 GHz, el múltiplo es 22. Históricamente, el TSC fue una fuente de tiempo poco confiable porque las implementaciones detendrían el contador cuando el procesador se durmió, o porque el múltiplo no era constante, ya que el procesador cambiaba los multiplicadores para cambiar los estados de rendimiento o acelerar cuando estaba caliente. Los procesadores x86 modernos proporcionan un TSC que es constante, invariable y sin interrupciones. En estos procesadores, el TSC es un excelente reloj de alta resolución y el kernel de Linux determina una frecuencia aproximada inicial en el momento del arranque. El TSC proporciona una resolución de microsegundos para la llamada al sistema gettimeofday () y la resolución en nanosegundos para la llamada al sistema clock_gettime ().

¿Cómo se realiza esta sincronización?

Su primera pregunta fue acerca de cómo el reloj de Linux proporciona alta resolución, esta segunda pregunta es sobre la sincronización, esta es la distinción entre precisión y precisión . La mayoría de los sistemas tienen un reloj respaldado por la batería para mantener la hora del día cuando el sistema está apagado. Como es de esperar, este reloj no tiene alta precisión o precisión, pero hará que la hora del día "en el estadio" comience cuando el sistema comience. Para obtener precisión, la mayoría de los sistemas usan un componente opcional para obtener tiempo de una fuente externa en la red. Dos comunes son

  1. Protocolo de tiempo de red
  2. Protocolo de tiempo de precisión

Estos protocolos definen un reloj maestro en la red (o un nivel de relojes originados por un reloj atómico) y luego miden las latencias de la red para estimar las compensaciones del reloj maestro. Una vez que se determina el desplazamiento del maestro, el reloj del sistema se disciplined para mantenerlo preciso. Esto puede hacerse por

  1. Al pisar el reloj (un ajuste de tiempo relativamente grande, abrupto e infrecuente), o
  2. Slewing del reloj (definido como cuánto debe ajustarse la frecuencia del reloj aumentando o disminuyendo lentamente la frecuencia en un período de tiempo determinado)

El núcleo proporciona la adjtimex() al adjtimex() para permitir la adjtimex() reloj. Para obtener detalles sobre cómo los procesadores multi-core de Intel modernos mantienen el TSC sincronizado entre los núcleos, consulte la operación de recuperación TSC de la CPU, especialmente en el entorno multinúcleo-multiprocesador .

Los archivos fuente del kernel relevantes para los ajustes del reloj son kernel/time.c y Linux/kernel/time/timekeeping.c .