
El contador de marca de tiempo ( TSC ) es un registro de 64 bits presente en todos los procesadores x86 desde el Pentium . Cuenta el número de ciclos de CPU desde su reinicio. La instrucción devuelve el TSC en EDX:EAX. En modo x86-64 , también borra los 32 bits superiores de RAX y RDX . Su código de operación es . [ 1 ] Los competidores del Pentium , como el Cyrix 6x86, no siempre tuvieron un TSC y pueden considerar una instrucción ilegal. Cyrix incluyó un contador de marca de tiempo en su MII .RDTSCRDTSC0F 31RDTSC
Usar
El contador de marca de tiempo (TSC) fue en su momento una forma de alta resolución y bajo consumo de recursos para que un programa obtuviera información de temporización de la CPU. Con la llegada de las CPU multinúcleo / hiper-hilo , los sistemas con múltiples CPU y los sistemas operativos con hibernación , no se puede confiar en el TSC para obtener resultados precisos, a menos que se tomen precauciones extremas para corregir posibles fallos: la frecuencia de reloj y si todos los núcleos (procesadores) tienen valores idénticos en sus registros de temporización. No hay garantía de que los contadores de marca de tiempo de múltiples CPU en una misma placa base estén sincronizados. Por lo tanto, un programa solo puede obtener resultados fiables si se limita a ejecutarse en una CPU específica. Incluso en ese caso, la velocidad de la CPU puede variar debido a las medidas de ahorro de energía del sistema operativo o la BIOS , o el sistema puede hibernar y reanudarse posteriormente, reiniciando el TSC. En estos últimos casos, para mantener la relevancia, el programa debe recalibrar el contador periódicamente.
Depender del TSC también reduce la portabilidad, ya que otros procesadores podrían no tener una característica similar. Los procesadores Intel recientes incluyen un TSC de tasa constante (identificado por el sysctl kern.timecounter.invariant_tsc en FreeBSD o por la constant_tscbandera " " en Linux /proc/cpuinfo). Con estos procesadores, el TSC funciona a la frecuencia nominal del procesador, independientemente de la frecuencia real del reloj de la CPU debido a los estados turbo o de ahorro de energía. Por lo tanto, los ciclos del TSC cuentan el paso del tiempo, no el número de ciclos de reloj de la CPU transcurridos.
En plataformas Windows , Microsoft desaconseja encarecidamente el uso del TSC para la sincronización de alta resolución precisamente por estas razones, proporcionando en su lugar las API de WindowsQueryPerformanceCounter y QueryPerformanceFrequency(que a su vez utiliza RDTSCP si el sistema tiene un TSC invariante, es decir, la frecuencia del TSC no varía según la frecuencia del núcleo actual). [ 2 ] En sistemas Linux , un programa puede obtener una función similar leyendo el valor del CLOCK_MONOTONIC_RAWreloj mediante la clock_gettimefunción. [ 3 ]
Desde el Pentium Pro , los procesadores Intel han practicado la ejecución fuera de orden , donde las instrucciones no se ejecutan necesariamente en el orden en que aparecen en el programa. Esto puede hacer que el procesador se ejecute RDTSCantes de lo que espera un programa simple, produciendo un conteo de ciclos engañoso. [ 4 ] El programador puede resolver este problema insertando una instrucción de serialización, como CPUID , para forzar que cada instrucción precedente se complete antes de permitir que el programa continúe. La RDTSCPinstrucción es una variante de RDTSCque presenta una serialización parcial del flujo de instrucciones, pero no debe considerarse como serialización.
Implementación en diversos procesadores
Las familias de procesadores Intel incrementan el contador de marca de tiempo de manera diferente: [ 5 ]
- Para los procesadores Pentium M (familia [06H], modelos [09H, 0DH]); para los procesadores Pentium 4, procesadores Intel Xeon (familia [0FH], modelos [00H, 01H o 02H]); y para los procesadores de la familia P6: el contador de marca de tiempo se incrementa con cada ciclo de reloj interno del procesador. El ciclo de reloj interno del procesador viene determinado por la relación actual entre la frecuencia del reloj del núcleo y la del bus. Las transiciones de la tecnología Intel SpeedStep también pueden afectar a la frecuencia del procesador.
- Para procesadores Pentium 4 , procesadores Intel Xeon (familia [0FH], modelos [03H y superiores]); para procesadores Intel Core Solo e Intel Core Duo (familia [06H], modelo [0EH]); para la serie de procesadores Intel Xeon 5100 y procesadores Intel Core 2 Duo (familia [06H], modelo [0FH]); para procesadores Intel Core 2 e Intel Xeon (familia [06H], display_model [17H]); para procesadores Intel Atom (familia [06H], display_model [1CH]): el contador de marca de tiempo se incrementa a una velocidad constante. Dicha velocidad puede estar determinada por la relación máxima entre la frecuencia del núcleo y la frecuencia del bus del procesador, o bien por la frecuencia máxima resuelta a la que se inicia el procesador. La frecuencia máxima resuelta puede diferir de la frecuencia máxima cualificada del procesador.
La configuración específica del procesador determina su comportamiento. El comportamiento constante del TSC garantiza que la duración de cada pulso de reloj sea uniforme y permite utilizar el TSC como temporizador de reloj de pared incluso si el núcleo del procesador cambia de frecuencia. Este es el comportamiento arquitectónico de todos los procesadores Intel posteriores.
Los procesadores AMD hasta el núcleo K8 siempre incrementaban el contador de marca de tiempo en cada ciclo de reloj. [ 6 ] Por lo tanto, las funciones de administración de energía podían cambiar el número de incrementos por segundo, y los valores podían desincronizarse entre diferentes núcleos o procesadores en el mismo sistema. Para Windows, AMD proporciona una utilidad [ 7 ] para sincronizar periódicamente los contadores en CPU de múltiples núcleos. Desde la familia 10h (Barcelona/Phenom), los chips AMD cuentan con un TSC constante, que puede ser impulsado por la velocidad de HyperTransport o el estado P más alto. Un bit CPUIDFn8000_0007:EDX_8 ( ) anuncia esto; las CPU Intel también informan su TSC invariante en ese bit.
Uso del sistema operativo
Un sistema operativo puede proporcionar métodos que usan y no usan la RDTSCinstrucción para el control del tiempo, bajo el control del administrador. Por ejemplo, en algunas versiones del kernel de Linux , el modo de aislamiento seccomp lo desactiva RDTSC. [ 8 ] También se puede desactivar usando el PR_SET_TSCargumento de la prctl()llamada al sistema. [ 9 ]
Uso en la explotación de ataques de canal lateral de caché
El contador de marca de tiempo se puede usar para cronometrar instrucciones con precisión, lo cual puede ser explotado en las vulnerabilidades de seguridad Meltdown y Spectre . [ 10 ] [ 11 ] Sin embargo, si esto no está disponible, se pueden usar otros contadores o temporizadores, como es el caso de los procesadores ARM vulnerables a este tipo de ataque.
Otras arquitecturas
Otros procesadores también cuentan con registros que contabilizan los ciclos de reloj de la CPU, pero con nombres diferentes. Por ejemplo, en el AVR32 se denomina registro Contador de Reloj de Rendimiento (PCCNT). SPARC V9 proporciona este TICKregistro. PowerPC proporciona el registro de 64 bits TBR.
ARMv7 proporciona un registro de contador de ciclos CCNT como parte de su "Unidad de monitorización del rendimiento" e instrucciones para leer y escribir el contador, pero el contador está deshabilitado por defecto (para ahorrar energía) y las instrucciones son privilegiadas. [ 12 ] Se puede habilitar el acceso en modo usuario. [ 13 ] Las arquitecturas ARMv7 [ 14 ] y ARMv8-A [ 15 ] proporcionan un contador genérico que cuenta a una frecuencia constante, pero esta frecuencia suele ser como máximo de 50 MHz. [ 16 ]
Véase también
Referencias
- ↑ Manual del desarrollador de software de las arquitecturas Intel 64 e IA-32, Volumen 2B: Referencia del conjunto de instrucciones, MZ (PDF) . pág. 545.
- ↑ Sincronización de juegos y procesadores multinúcleo . págs. 251–252 .
- ↑ "clock_getres, clock_gettime, clock_settime - funciones de reloj y temporizador" .
- ↑ "Uso de la instrucción RDTSC para la monitorización del rendimiento" (PDF) .
- ↑ "Volumen 3A, Capítulo 16". Manual del desarrollador de software para arquitecturas Intel 64 e IA-32 .
- ↑ "Volumen 3". Manual del programador de la arquitectura AMD64 .
- ↑ "Optimizador de doble núcleo de AMD" .
- ↑ "Blog de cr0: Deshabilitación de peculiaridades del contador de marcas de tiempo en el kernel de Linux" . Mayo de 2009.
- ↑ – Manual del programador de Linux – Llamadas al sistema
- ↑ "meltdown.c" .
- ↑ "spectre.c" .
- ↑ "Registro de contador de ciclos (CCNT)" . ARM Ltd. Consultado el 5 de marzo de 2021 .
- ↑ Protsenko, Sam (14 de julio de 2010). "¿Cómo medir el tiempo de ejecución de un programa en un procesador ARM Cortex-A8?" . Stack Overflow .
- ↑ "Manual de referencia de ARMv7" .
- ↑ "Manual de referencia de ARMv8" .
- ↑ Guías del programador de AArch64: Temporizador genérico (PDF) (Manual). ARM Ltd. 13 de agosto de 2019. pág. 6. ARM062-1010708621-30.
El valor del contador del sistema tiene un ancho de entre 56 y 64 bits, con una frecuencia que suele oscilar entre 1 MHz y 50 MHz.
Enlaces externos
- cycle.h - Código C para leer el temporizador de alta resolución en muchos procesadores y compiladores.
- Ingeniero de AMD habla sobre la deriva del TSC en los procesadores AMD.
- Arquitectura X86