Simuladores de sistemas informáticos: el familiar simulador de plataforma completa y desconocido para cualquier toque y pista

En la segunda parte del artículo sobre simuladores de sistemas informáticos, continuaré hablando en una forma introductoria simple sobre simuladores de computadora, es decir, sobre la simulación de plataforma completa, que suele encontrar un usuario ordinario, así como sobre el modelo y las huellas ciclo por ciclo, que son más comunes en los círculos de desarrollo.



imagen



En la primera parte, hablé sobre los simuladores en general, así como sobre los niveles de simulación. Ahora, en base a ese conocimiento, propongo profundizar un poco más y hablar sobre la simulación de plataforma completa, cómo ensamblar pistas, qué hacer con ellas más adelante, así como la emulación microarquitectura ciclo por ciclo.



Simulador de plataforma completa, o "Solo en el campo, no un guerrero"



Si necesita investigar el funcionamiento de un dispositivo específico, por ejemplo, una tarjeta de red, o escribir un firmware o controlador para este dispositivo, dicho dispositivo se puede modelar por separado. Sin embargo, usarlo de forma aislada del resto de la infraestructura no es muy conveniente. Para iniciar el controlador correspondiente, necesitará un procesador central, memoria, acceso al bus para la transferencia de datos, etc. Además, el controlador requiere un sistema operativo (SO) y una pila de red. Además, se puede requerir un generador de paquetes y un servidor de respuesta separados.



El simulador de plataforma completa crea un entorno para ejecutar una pila completa de software, que incluye todo, desde el BIOS y el gestor de arranque hasta el sistema operativo y sus diversos subsistemas, como la misma pila de red, controladores y aplicaciones de nivel de usuario. Para ello, implementa modelos de software de la mayoría de los dispositivos informáticos: procesador y memoria, disco, dispositivos de entrada y salida (teclado, mouse, pantalla), así como la misma tarjeta de red.



A continuación se muestra un diagrama de bloques del chipset x58 de Intel. Un simulador de computadora de plataforma completa en este conjunto de chips requiere la implementación de la mayoría de los dispositivos enumerados, incluidos los que están dentro del IOH (Hub de entrada / salida) y ICH (Hub del controlador de entrada / salida), que no se dibujan en detalle en el diagrama de bloques. Aunque, como muestra la práctica, no hay tan pocos dispositivos que el software no utilice que vamos a lanzar. No es necesario crear modelos de tales dispositivos.



imagen



Muy a menudo, los simuladores de plataforma completa se implementan en el nivel de instrucción del procesador (ISA, ver artículo anterior) Esto le permite crear el simulador en sí de forma relativamente rápida y económica. El nivel ISA también es bueno porque permanece más o menos constante, a diferencia, por ejemplo, del nivel API / ABI, que cambia con más frecuencia. Además, la implementación en el nivel de instrucción le permite ejecutar el denominado software binario no modificado, es decir, ejecutar el código ya compilado sin ningún cambio, exactamente como se usa en el hardware real. En otras palabras, puede hacer una copia ("volcado") de su disco duro, especificarla como una imagen para un modelo en un simulador de plataforma completa, ¡y listo! - El sistema operativo y otros programas se cargan en el simulador sin ninguna acción adicional.



Rendimiento del simulador





imagen



Como se mencionó anteriormente, el proceso mismo de simular todo el sistema en su conjunto, es decir, todos sus dispositivos, es un ejercicio bastante lento. Si también implementa todo esto a un nivel muy detallado, por ejemplo, microarquitectura o lógica, la ejecución será extremadamente lenta. Pero el nivel de instrucciones es una opción adecuada y permite que el sistema operativo y los programas se ejecuten a velocidades suficientes para que el usuario interactúe cómodamente con ellos.



Aquí será apropiado tocar el tema del rendimiento del simulador. Por lo general, se mide en IPS (instrucciones por segundo), más precisamente en MIPS (millones de IPS), es decir, el número de instrucciones de procesador ejecutadas por el simulador por segundo. Al mismo tiempo, la velocidad de la simulación también depende del rendimiento del sistema en el que se ejecuta la simulación. Por lo tanto, puede ser más correcto hablar sobre la "desaceleración" del simulador en comparación con el sistema original.



Los simuladores de plataforma completa más comunes en el mercado, como QEMU, VirtualBox o VmWare Workstation, tienen un buen rendimiento. Puede que ni siquiera sea notorio para el usuario que el trabajo está sucediendo en el simulador. Esto se debe a las capacidades especiales de virtualización implementadas en los procesadores, algoritmos de traducción binaria y otras cosas interesantes. Todo esto es un tema para un artículo separado, pero en resumen, la virtualización es una característica de hardware de los procesadores modernos, que permite a los simuladores no simular instrucciones, sino enviarlas para su ejecución directamente a un procesador real, si, por supuesto, las arquitecturas del simulador y el procesador son similares. La traducción binaria es la traducción del código de máquina huésped en el código de host y la posterior ejecución en un procesador real. Como resultado, la simulación es solo un poco más lenta, cada 5-10 veces,y a menudo generalmente funciona a la misma velocidad que el sistema real. Aunque esto está influenciado por muchos factores. Por ejemplo, si queremos simular un sistema con varias decenas de procesadores, la velocidad disminuirá inmediatamente varias decenas de veces. Por otro lado, los simuladores como Simics en versiones recientes admiten hardware host multiprocesador y paralelizan efectivamente núcleos simulados a los núcleos de un procesador real.Los simuladores como Simics en versiones recientes admiten hardware host multiprocesador y paralelizan efectivamente núcleos simulados a núcleos de procesador reales.Los simuladores como Simics en versiones recientes admiten hardware host multiprocesador y paralelizan efectivamente núcleos simulados a núcleos de procesador reales.



Si hablamos de la velocidad de la simulación microarquitectónica, generalmente es de varios órdenes de magnitud, aproximadamente 1000-10000 veces más lenta que la ejecución en una computadora normal, sin simulación. Y las implementaciones a nivel de elementos lógicos son más lentas en varios órdenes de magnitud. Por lo tanto, FPGA se utiliza como un emulador en este nivel, lo que puede aumentar significativamente el rendimiento.



El siguiente gráfico muestra la dependencia aproximada de la velocidad de simulación del detalle del modelo.



imagen



Simulación de fondo



A pesar de la baja velocidad de ejecución, las simulaciones microarquitectónicas son bastante comunes. Es necesario modelar los bloques internos del procesador para simular con precisión el tiempo de ejecución de cada instrucción. Aquí puede surgir un malentendido; después de todo, parecería, ¿por qué no simplemente tomar y programar el tiempo de ejecución de cada instrucción? Pero dicho simulador funcionará de manera muy imprecisa, ya que el tiempo de ejecución de la misma instrucción puede diferir de una llamada a otra.



El ejemplo más simple es una instrucción de acceso a memoria. Si la ubicación de memoria solicitada está disponible en la memoria caché, el tiempo de ejecución será mínimo. Si no hay dicha información en el caché ("error de caché", error de caché), esto aumentará en gran medida el tiempo de ejecución de la instrucción. Por lo tanto, se necesita un modelo de caché para una simulación precisa. Sin embargo, el modelo de caché no se limita a esto. El procesador no solo esperará los datos de la memoria si no está en la memoria caché. En cambio, comenzará a ejecutar las siguientes instrucciones, eligiendo las que sean independientes del resultado de la lectura de memoria. Esta es la llamada ejecución fuera de orden (OOO) requerida para minimizar el tiempo de inactividad del procesador. La simulación de los bloques de procesador correspondientes ayudará a tener todo esto en cuenta al calcular el tiempo de ejecución de las instrucciones. Entre estas instrucciones que se ejecutan,mientras espera el resultado de la lectura de la memoria, puede ocurrir una operación de ramificación condicional. Si el resultado del cumplimiento de la condición es desconocido en este momento, nuevamente el procesador no detiene la ejecución, sino que hace una "suposición", realiza la transición correspondiente y continúa ejecutando instrucciones de manera preventiva desde el lugar de la transición. Tal bloque, llamado predictor de ramificación, también debe implementarse en el simulador de microarquitectura.



La siguiente imagen muestra los bloques principales del procesador, no es necesario conocerlo, solo se muestra para mostrar la complejidad de la implementación de la microarquitectura.



imagen



El funcionamiento de todos estos bloques en un procesador real se sincroniza con señales de reloj especiales, y lo mismo sucede en el modelo. Este simulador de microarquitectura se llama ciclo exacto. Su objetivo principal es predecir con precisión el rendimiento del procesador que se está desarrollando y / o calcular el tiempo de ejecución de un determinado programa, por ejemplo, un punto de referencia. Si los valores son más bajos de lo necesario, deberá refinar los algoritmos y las unidades de procesador u optimizar el programa.



Como se muestra arriba, la simulación en tiempo real es muy lenta, por lo que se usa solo cuando se estudian ciertos momentos del programa, donde debe averiguar la velocidad real de los programas y evaluar el rendimiento futuro del dispositivo, cuyo prototipo se está modelando.



En este caso, se utiliza un simulador funcional para simular el resto del tiempo de ejecución del programa. ¿Cómo se produce realmente este uso combinado? Primero, se lanza un simulador funcional, en el que se cargan el sistema operativo y todo lo necesario para ejecutar el programa en estudio. Después de todo, no estamos interesados ​​ni en el sistema operativo en sí, ni en las etapas iniciales del lanzamiento del programa, su configuración, etc. Sin embargo, no podemos omitir estas partes e inmediatamente proceder a la ejecución del programa desde el medio. Por lo tanto, todos estos pasos preliminares se ejecutan en un simulador funcional. Después de ejecutar el programa hasta el momento que nos interesa, hay dos opciones. Puede reemplazar el modelo con uno ciclo por ciclo y continuar la ejecución. Modo de simulación, en el que se utiliza el código ejecutable (es decir, archivos de programa compilados regulares),referido como simulación dirigida por ejecución. Esta es la opción de simulación más común. También es posible otro enfoque: la simulación impulsada por rastreo.



Simulación basada en rastreo



Consiste en dos pasos. Usando un simulador funcional o en un sistema real, el registro de acción del programa se recopila y se escribe en un archivo. Tal registro se llama rastro. Dependiendo de lo que se esté investigando, el rastreo puede incluir instrucciones ejecutables, direcciones de memoria, números de puerto, información sobre interrupciones.



El siguiente paso es "reproducir" la traza, cuando el simulador ciclo por reloj lee la traza y ejecuta todas las instrucciones escritas en ella. Al final, obtenemos el tiempo de ejecución de un determinado programa, así como diversas características de este proceso, por ejemplo, el porcentaje de aciertos de caché.



Una característica importante de trabajar con trazas es el determinismo, es decir, al comenzar la simulación de la manera descrita anteriormente, una y otra vez reproducimos la misma secuencia de acciones. Esto hace posible, al cambiar los parámetros del modelo (los tamaños de la memoria caché, las memorias intermedias y las colas) y usar diferentes algoritmos internos o ajustarlos, para investigar cómo este o aquel parámetro afecta el rendimiento del sistema y qué opción da los mejores resultados. Todo esto se puede hacer con un modelo de dispositivo prototipo antes de crear un prototipo de hardware real.



La complejidad de este enfoque radica en la necesidad de ejecutar previamente la aplicación y recopilar la traza, así como el gran tamaño de archivo con la traza. Las ventajas incluyen el hecho de que es suficiente simular solo la parte del dispositivo o plataforma de interés, mientras que la simulación de ejecución generalmente requiere un modelo completo.



Entonces, en este artículo, examinamos las características de la simulación de plataforma completa, hablamos sobre la velocidad de las implementaciones en diferentes niveles, simulación ciclo por ciclo y trazas. En el siguiente artículo, describiré los principales escenarios para usar simuladores, tanto para fines personales como en términos de desarrollo en grandes empresas.



All Articles