performance - significa - ¿Por qué RDTSC no es una instrucción de serialización?
x86 que significa (4)
¿Por qué no hicieron la serialización de RDTSC? Todo parece indicar que se trata de obtener tiempos de ciclo precisos
Bueno, la mayoría de las veces es para obtener sellos de tiempo de alta resolución. Al menos algunas veces, estas marcas de tiempo se usan para medir el rendimiento. Hacer la serialización de la construcción probablemente requiera un enjuague de la tubería, que puede ser muy costoso para las aplicaciones de CPU.
Intel optó por introducir una instrucción separada en lugar de cambiar el comportamiento de RDTSC, lo que me sugiere que tiene que haber alguna situación en la que un tiempo potencialmente fuera de servicio sea lo que desee.
Cambiar el comportamiento casi siempre es indeseable. Los clientes de Intel estarían decepcionados al descubrir que RDTSC
hace algo diferente en las partes más nuevas.
Los manuales de Intel para la instrucción RDTSC advierten que la ejecución fuera de servicio puede cambiar cuando RDTSC se ejecuta realmente, por lo que recomiendan insertar una instrucción CPUID delante de ella porque el CPUID serializará la secuencia de instrucciones (CPUID nunca se ejecuta fuera de servicio). Mi pregunta es simple: si tuvieran la capacidad de hacer serializaciones de instrucciones, ¿por qué no hicieron la serialización de RDTSC? Todo parece indicar que se deben obtener tiempos de ciclo precisos. ¿Hay alguna situación en la que no desee precederla con una instrucción de serialización?
Las CPU Intel más nuevas tienen una instrucción RDTSCP separada que se está serializando. Intel optó por introducir una instrucción separada en lugar de cambiar el comportamiento de RDTSC, lo que me sugiere que tiene que haber alguna situación en la que un tiempo potencialmente fuera de servicio sea lo que desee. ¿Qué es?
Como paxdiably explica, RDTSC
es anterior al concepto de "serialización" de instrucciones porque se implementó en una CPU en orden. Agregar ese comportamiento más tarde cambiaría el comportamiento de acceso a la memoria del código que lo usa y, por lo tanto, sería incompatible para algunos propósitos.
En cambio, las CPU más recientes tienen una instrucción RDTSCP
relacionada que se define como serialización (en realidad más sólida: promete esperar hasta que se hayan completado todas las instrucciones antes, no solo que se hayan hecho los accesos a la memoria), exactamente por este motivo. Úselo si está ejecutando CPU modernas.
Porque el contador de marca de tiempo fue, de memoria, introducido en el Pentium.
La ejecución fuera de orden no apareció hasta el Pentium Pro, en ese momento ya era demasiado tarde para cambiar lo que hacía la instrucción.
Eso está realmente confirmado (obtusamente) en el documento que usted proporciona, con el siguiente comentario sobre Pentium y Pentium / MMX (en 4.2, levemente parafraseado):
Todas las reglas y ejemplos de código descritos en la sección 4.1 (Pentium Pro y Pentium II) también se aplican al Pentium y Pentium / MMX. La única diferencia es que la instrucción CPUID no es necesaria para la serialización.
Y, de Wikipedia :
El Contador de sellos de tiempo es un registro de 64 bits presente en todos los procesadores x86 desde el Pentium.
:::
Comenzando con el Pentium Pro, los procesadores Intel han soportado la ejecución fuera de orden, donde las instrucciones no se realizan necesariamente en el orden en que aparecen en el ejecutable. Esto puede hacer que RDTSC se ejecute más tarde de lo esperado, lo que produce un recuento de ciclos confuso.
Y, por lo que entiendo, el uso principal de RDTSCP (desde el i7 en adelante) es darle la ID del procesador también, ya que cada procesador mantiene un TSC independiente. Puede ser una serialización, pero veo que se trata más de una simple "corrección de errores" sobre las instrucciones anteriores.
Si está intentando usar rdtsc para ver si una rama malpredicta, la versión no serializada es lo que desea.
//math here
rdtsc
branch if zero to done
//do some work that always takes 1 cycle
done: rdtsc
Si la ramificación se predice correctamente, el delta será pequeño (¿tal vez incluso negativo?). Si la rama es mal predicha, el delta será grande.
Con la versión de serialización, la condición de la sucursal se resolverá porque el primer rdtsc espera que el cálculo finalice.