Al construir una máquina virtual (VM) determinista diseñada para reproducir ejecuciones, los desarrolladores se enfrentan a un desafío fundamental: cómo representar el tiempo de manera consistente. El tiempo estándar del reloj de pared no es adecuado para las repeticiones porque el tiempo transcurrido entre dos puntos de un programa depende de factores externos como la carga de la CPU del host, los estados de la caché y otros procesos en ejecución. Si las decisiones de un programa invitado dependen de la hora actual, el uso del reloj de pared del host haría que el programa se comporte de manera diferente en cada ejecución, rompiendo el requisito central de determinismo.
Para resolver esto, la VM Rewind utiliza un mecanismo que mide el progreso a través del flujo de instrucciones del invitado en lugar del reloj del host. Aunque se podría considerar el uso de un recuento de instrucciones puras, el autor de Rewind demuestra que esto es poco fiable. En una prueba que involucra un bucle simple, el recuento de instrucciones varió porque el contador de hardware capturó eventos externos —como paquetes de red, interrupciones entre procesadores (IPIs) y fallos de página— que el propio programa invitado no puede ver. En contraste, el contador de ramas condicionales permanece estable porque solo se incrementa en función de la lógica interna del invitado, lo que lo convierte en un sustituto más fiable para el 'tiempo determinista'.

Este meme ilustra la elección de usar las ramas condicionales como métrica principal de tiempo en lugar de los recuentos de instrucciones puras.

Esta imagen explica la razón técnica por la cual los recuentos de instrucciones puras no logran proporcionar un sustituto de tiempo determinista.
Rewind ofrece dos modos principales para esta medición: 'tiempo de salida' (exit time) y 'tiempo de contador' (counter time). El tiempo de salida solo adelanta el reloj cuando el invitado realiza una llamada al sistema (syscall), tratando todo el cómputo interno como instantáneo. Aunque es simple, esto puede fallar al reproducir errores relacionados con tiempos de espera o condiciones de carrera específicas porque agrupa todo el trabajo en la misma franja de tiempo. El tiempo de contador, que adelanta un nanosegundo por cada rama condicional que el invitado procesa, proporciona una aproximación más realista del mundo real. Aunque el tiempo de contador sigue difiriendo del reloj de pared real del host (por ejemplo, midiendo 11.7 segundos para una tarea que tomó 14.2 segundos en el host), su consistencia garantiza que el mismo programa siempre producirá los mismos resultados en cada repetición.

Esta imagen sirve como un resumen del enfoque de la VM Rewind para medir el progreso a través de la lógica interna del invitado.