2012-06-06 71 views
12

En el mundo Linux, para conseguir temporizador nano segundos de precisión/clockticks se puede utilizar:CPU TSC operación de recuperación, especialmente en el entorno de múltiples núcleos de procesadores múltiples

#include <sys/time.h> 

int foo() 
{ 
    timespec ts; 

    clock_gettime(CLOCK_REALTIME, &ts); 
    //--snip--  
} 

This answer sugiere un enfoque asm para consultar directamente para el reloj de la CPU con la instrucción RDTSC.

En una arquitectura multi-core, multiprocesador, ¿cómo se sincroniza este reloj/valor del temporizador en varios núcleos/procesadores? Tengo entendido que se está haciendo una valla inherente. ¿Es este entendimiento correcto?

¿Puede sugerir alguna documentación que explique esto en detalle? Estoy interesado en las microarquitecturas Intel Nehalem y Sandy Bridge.

EDITAR

Limitar el proceso de un solo núcleo o CPU no es una opción, ya que el proceso es realmente enorme (en términos de recursos consumidos) y me gustaría utilizar de manera óptima todos los recursos de la máquina que incluye todos los núcleos y procesadores.

Editar

Gracias por la confirmación de que el TSC se sincroniza a través de núcleos y procesadores. Pero mi pregunta original es ¿cómo se hace esta sincronización? ¿Es con algún tipo de esgrima? ¿Conoces alguna documentación pública?

Conclusión

Gracias para todas las entradas: Aquí está la conclusión para esta discusión: Los TSCs se sincronizan en la inicialización utilizando un RESET que pasa a través de los núcleos y procesadores en un sistema multi procesador/multi núcleo. Y después de eso, cada núcleo está solo. Los TSC se mantienen invariables con un bucle de fase bloqueada que normalizaría las variaciones de frecuencia y, por lo tanto, las variaciones de reloj dentro de un núcleo determinado y así es como el TSC permanece sincronizado en los núcleos y procesadores.

+0

No se puede contar con clock_gettime() para la precisión de nanosegundos, por cierto; es solo preciso a aproximadamente un cuarto de microsegundo. Me encontré con esto cuando estaba tratando de obtener sincronizaciones súper precisas y descubrí que gettime() en sí cuesta más de 250ns. http://stackoverflow.com/questions/7935518/is-clock-gettime-adequate-for-submicrosecond-timing – Crashworks

+0

si se utiliza TSC para proporcionar la marca de tiempo, se supone que solo refleja delta nano segundos. Estoy usando linux. Y entiendo que kernel proporciona el rendimiento esperado. ventanas - puede ser no. –

+0

@Crashworks pls lea mi último comentario sobre este enlace de la pregunta que compartió. –

Respuesta

12

En las CPU más nuevas (i7 Nehalem + IIRC), el TSC se sincroniza en todos los núcleos y ejecuta una velocidad constante. Por lo tanto, para un solo procesador o más de un procesador en un solo paquete o placa base (!) Puede confiar en un TSC sincronizado.

Desde el Intel System Manual 16.12.1

El contador de marca de tiempo en los procesadores más nuevos pueden apoyar una mejora, conoce como invariante TSC. La compatibilidad de los procesadores para TSC invariables es indicada por CPUID.80000007H: EDX [8]. El TSC invariable se ejecutará a una tasa constante de en todos los ACPI P-, C-. y T-estados. Este es el comportamiento arquitectónico de que avanza.

En los procesadores más antiguos no puede confiar ni en la velocidad constante ni en la sincronización.

Editar: Al menos en múltiples procesadores en un solo paquete o placa base, el TSC invariable está sincronizado. El TSC se restablece a cero en un/RESET y luego avanza a una velocidad constante en cada procesador, sin deriva. Se garantiza que la señal/RESET llegará a cada procesador al mismo tiempo.

+0

información interesante. Gracias. ! –

+1

Tenga en cuenta que solo se aplica a los procesadores Intel. Ha pasado un tiempo desde que realicé alguna prueba en AMD (la CPU AMD más reciente que probé fue, IIRC, el Phenom II), pero en ese momento ni siquiera tenían sincronización entre núcleos en un solo dado. – user434507

5

RTDSC no está sincronizado en todas las CPU. Por lo tanto, no puede confiar en un sistema multiprocesador. La única solución que se me ocurre para Linux sería restringir realmente el proceso para que se ejecute en una sola CPU configurando su afinidad. Esto puede hacerse externamente usando la utilidad taskset o "internamente" usando las funciones sched_setaffinity o pthread_setaffinity_np.

5

This manual, capítulo 17.12, describe el TSC invariable utilizado en los procesadores más nuevos. Disponible con Nehalem, esta marca de tiempo, junto con la instrucción rtscp, le permite a uno leer una marca de tiempo (no afectada por estados de espera, etc.) y una firma de procesador en una operación atómica.

Se dice que es adecuado para calcular el tiempo del reloj de pared, pero obviamente no espera que el valor sea el mismo en todos los procesadores. La idea establecida es que puede ver si las sucesivas lecturas son para el mismo reloj de la CPU, o para ajustar para múltiples lecturas de CPU. "También se puede usar para ajustar las diferencias por CPU en los valores de TSC en un sistema NUMA".

Ver también rdtsc accuracy across CPU cores

Sin embargo, no estoy seguro de que la conclusión de la consistencia final en la respuesta aceptada desprende de la declaración de que el TSC se puede utilizar para el tiempo de reloj de pared. Si fue consistente, ¿qué motivo habría para determinar atómicamente la fuente de la CPU del tiempo?

N. B. La información del TSC ha pasado del capítulo 11 al capítulo 17 en ese manual de Intel.

+0

'Si fuera consistente, ¿qué motivo habría para determinar atómicamente el origen de la CPU de la época ?: Esa es exactamente la pregunta que formulé como parte de esta discusión. –

+0

Y digo, dada la información en el manual, que hay buenas razones para creer que el tiempo es invariable en todos los estados de la CPU, pero no que se trate de CPU. Parece ser una inferencia que se está sacando, pero creo que su precaución está justificada. Tenga en cuenta que las instrucciones para leer la firma de la CPU también son nuevas. También sugiero que si el kernel establece el valor de tsc, su valor (fase) no será el mismo, incluso si los TSC son ejecutados por el mismo circuito de reloj y, por lo tanto, tienen frecuencias bloqueadas. –

20

Directamente de Intel, aquí hay una explicación de cómo los procesadores recientes mantienen un TSC que funciona a velocidad constante, es síncrono entre núcleos y paquetes en una placa base de múltiples zócalos, y puede incluso seguir funcionando cuando el procesador entra en una profundidad sueño C-estado, en particular, ver la explicación por Vipin Kumar EK (Intel):

http://software.intel.com/en-us/articles/best-timing-function-for-measuring-ipp-api-timing/

Aquí hay otra referencia de Intel discutir la sincronización de la TSC través de los núcleos, en este caso que mencionan el hecho de que rdtscp le permite leer el TSC y la ID del procesador atómicamente, esto es importante en las aplicaciones de rastreo ... suponga que desea rastrear la ejecución de un hilo que puede migrar de un núcleo a otro, si haces eso en dos instrucciones separadas (no atómicas), entonces no tienes la certeza de cuál es el núcleo del hilo en el momento en que lee el reloj.

http://software.intel.com/en-us/articles/intel-gpa-tip-cannot-sychronize-cpu-timestamps/

Todos los zócalos/paquetes en una placa base reciben dos señales comunes externos:

  1. REPONER
  2. referencia de reloj

Todos los zócalos ver restablecido al mismo tiempo cuando se alimentar la placa base, todos los paquetes de procesador reciben una señal de reloj de referencia de un oscilador de cristal externo y el clo interno Los cks en el procesador se mantienen en fase (aunque generalmente con un alto multiplicador, como 25x) con un circuito llamado Phase Locked Loop (PLL). Los procesadores recientes sincronizarán el TSC a la frecuencia más alta (multiplicador) que el procesador califica (llamado TSC constante), independientemente del multiplicador que cualquier núcleo individual pueda estar utilizando debido a la regulación de la temperatura o la administración de potencia (llamado TSC invariante).Los procesadores Nehalem como el X5570 lanzado en 2008 (y los procesadores Intel más nuevos) admiten un "TSC sin paradas" que continuará funcionando incluso cuando se conserva energía en un estado C de baja potencia (C6). Vea este enlace para más información sobre los diferentes estados de energía abajo:

http://www.anandtech.com/show/2199

Sobre la investigación adicional me encontré con una patente Intel presentada el 12/22/2009 y publicado el 6/23/2011 titulado "Control tiempo contador de marca (TSC) Desplazamientos destino para varios núcleos e hilos"

http://www.freepatentsonline.com/y2011/0154090.html

la página de Google para esta solicitud de patente (con enlace a la página USPTO)

http://www.google.com/patents/US20110154090

Por lo que veo hay un TSC en el uncore (la lógica en un paquete que rodea los núcleos pero no parte de ningún núcleo) que se incrementa en cada reloj de bus externo por el valor en el campo de la máquina específica registro especificado por Vipin Kumar en el enlace de arriba (MSR_PLATFORM_INFO [15: 8]). El reloj del bus externo funciona a 133.33MHz. Además, cada núcleo tiene su propio registro TSC, sincronizado por un dominio de reloj que es compartido por todos los núcleos y puede ser diferente del reloj para cualquier núcleo; por lo tanto, debe haber algún tipo de buffer cuando el RDTSC lee el TSC central. (o RDTSCP) que se ejecuta en un núcleo. Por ejemplo, MSR_PLATFORM_INFO [15: 8] puede establecerse en 25 en un paquete, cada reloj de bus el TSC no clave aumenta en 25, hay un PLL que multiplica el reloj del bus por 25 y proporciona este reloj a cada uno de los núcleos para su registro TSC local, manteniendo así todos los registros TSC sincronizados. Así que para mapear la terminología de hardware real

  • TSC constante se implementa utilizando el reloj de bus externo funcionando a 133,33 MHz que se multiplica por un factor constante especificada en MSR_PLATFORM_INFO [15: 8]
  • invariante TSC es implementado al mantener el TSC en cada núcleo en un dominio de reloj separado
  • El TSC sin parada se implementa teniendo un TSC de uncore que se incrementa mediante tics MSR_PLATFORM_INFO [15: 8] en cada reloj del bus, de ese modo un paquete de múltiples núcleos puede entra en un apagado profundo (estado C6) y puede apagar el PLL ... no hay necesidad de mantener un reloj en el multiplicador superior. Cuando un núcleo se reanuda desde el estado C6, su TSC interno se inicializará al valor del TSC no estándar (el que no se durmió) con un ajuste de compensación en caso de que el software haya escrito un valor para el TSC, los detalles de que están en la patente. Si el software escribe en el TSC, entonces el TSC para ese núcleo estará desfasado con otros núcleos, pero con un desfase constante (la frecuencia de los relojes del TSC está ligada al reloj de referencia del bus mediante un multiplicador constante).
+1

Gracias por su respuesta. Su primer enlace habla de un contenedor de tiempo en la biblioteca de Intel IPP. IPP es una biblioteca de procesamiento de imágenes. El enlace simplemente establece el mismo hecho mencionado anteriormente, que los TSC están sincronizados entre los núcleos en los procesadores modernos. pero no proporciona la razón por la cual - La pregunta original.! –

+0

Su segundo enlace se refiere a cómo informan los chips Intel Graphics si los TSC no están sincronizados. y cómo se las arreglan con los delta TSC. el artículo realmente no habla sobre cómo los TSCs están sincronizados. –

+0

tercer enlace habla sobre las características de nehalem. y Phase Locked Loop (PLL) normalizaría el reloj para un Núcleo dado, NO A TRAVÉS de Cores y entre procesadores. –

Cuestiones relacionadas