Simuladores de sistemas informáticos: el conocido simulador de plataforma completa y los poco conocidos modelos por ciclos y rutas.

En la segunda parte del artículo sobre simuladores de sistemas informáticos, continuaré explicando de manera sencilla sobre los simuladores informáticos, específicamente sobre la simulación de plataforma completa, con la que el usuario común se encuentra más a menudo, así como sobre el modelo por ciclos y las rutas, que son más comunes en los círculos de desarrolladores.

Simuladores de sistemas informáticos: el conocido simulador de plataforma completa y los poco conocidos modelos por ciclos y rutas.

En parte anterior Ya he explicado qué son los simuladores en general, así como los niveles de modelado. Ahora, basándome en esos conocimientos, propongo profundizar un poco más y hablar sobre la simulación de plataforma completa, cómo construir rutas, qué hacer con ellas después, y sobre la emulación arquitectónica de ciclos.

Simulador de plataforma completa (full platform simulator), o “Uno solo en el campo no es un guerrero”.

Si se requiere investigar el funcionamiento de un dispositivo concreto, como una tarjeta de red, o escribir un firmware o un controlador para este dispositivo, se puede modelar por separado. Sin embargo, utilizarlo aislado del resto de la infraestructura no es muy práctico. Para ejecutar el controlador correspondiente se necesitará un procesador central, memoria, acceso al bus para la transferencia de datos, entre otros. Además, para el funcionamiento del controlador se requiere un sistema operativo (SO) y un stack de red. También puede ser necesario un generador de paquetes separado y un servidor para recibir respuestas.

Un simulador de plataforma completa crea un entorno para ejecutar toda la pila de software, que incluye todo desde la BIOS y el cargador hasta el propio SO y varios de sus subsistemas, como el stack de red, controladores y aplicaciones de nivel de usuario. Para ello, implementa modelos de software de la mayoría de los dispositivos de la computadora: el procesador y la memoria, el disco, dispositivos de entrada y salida (teclado, ratón, pantalla), así como esa misma tarjeta de red.

A continuación se presenta el diagrama de bloques del chipset x58 de Intel. En un simulador de computadora de plataforma completa basado en este chipset, es necesario implementar la mayoría de los dispositivos enumerados, incluidos aquellos que se encuentran dentro del IOH (Input/Output Hub) y el ICH (Input/Output Controller Hub), que no están representados con detalle en el diagrama de bloques. Sin embargo, como demuestra la práctica, hay una cantidad considerable de dispositivos que no son utilizados por el software que planeamos ejecutar. No es necesario crear modelos de estos dispositivos.

Simuladores de sistemas informáticos: el conocido simulador de plataforma completa y los poco conocidos modelos por ciclos y rutas.

Con más frecuencia, los simuladores de plataforma completa se implementan a nivel de instrucciones del procesador (ISA, ver el artículo anterior). Esto permite crear el simulador de manera relativamente rápida y económica. El nivel ISA también es bueno porque permanece más o menos constante, a diferencia del nivel API/ABI, que cambia con más frecuencia. Además, la implementación a nivel de instrucciones permite ejecutar lo que se denomina software binario no modificado, es decir, ejecutar código ya compilado sin ningún cambio, tal como se utiliza en el hardware real. En otras palabras, se puede hacer una copia (“dump”) del disco duro, especificarlo como imagen para el modelo en el simulador de plataforma completa y – ¡voilà! – el sistema operativo y otros programas se cargan en el simulador sin necesidad de acciones adicionales.

Rendimiento de los simuladores

Simuladores de sistemas informáticos: el conocido simulador de plataforma completa y los poco conocidos modelos por ciclos y rutas.

Como se mencionó anteriormente, el proceso de simular todo el sistema en su totalidad, es decir, todos sus dispositivos, es un proceso bastante lento. Si además se implementa todo a un nivel muy detallado, como a nivel microarquitectónico o lógico, la ejecución se volverá extremadamente lenta. Sin embargo, el nivel de instrucciones es una elección adecuada y permite que el sistema operativo y los programas se ejecuten a velocidades suficientes para que el usuario pueda interactuar cómodamente con ellos.

Aquí es pertinente abordar el tema del rendimiento de los simuladores. Generalmente, se mide en IPS (instrucciones por segundo), más precisamente en MIPS (millones de IPS), es decir, el número de instrucciones del procesador que el simulador ejecuta en un 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, quizás sea más correcto hablar de "ralentización" (slowdown) del simulador en comparación con el sistema original.

Los simuladores de plataformas completas más comúnmente utilizados en el mercado, como QEMU, VirtualBox o VmWare Workstation, ofrecen un rendimiento bastante bueno. Para el usuario, puede que ni siquiera se note que está trabajando en un simulador. Esto se debe a la capacidad de virtualización especial implementada en los procesadores, los algoritmos de traducción binaria y otras cosas interesantes. Todo esto es un tema para un artículo aparte, pero en resumen, la virtualización es una capacidad de hardware de los procesadores modernos que permite a los simuladores ejecutar instrucciones directamente en el procesador real, siempre que, por supuesto, las arquitecturas del simulador y del procesador sean similares. La traducción binaria es la conversión del código de máquina del huésped al del anfitrión y su posterior ejecución en el procesador real. Como resultado, la simulación es solo un poco más lenta, de 5 a 10 veces, y a menudo funciona a la misma velocidad que un sistema real. Sin embargo, muchos factores influyen en esto. Por ejemplo, si queremos simular un sistema con varias decenas de procesadores, la velocidad disminuirá drásticamente en esas mismas decenas. Por otro lado, simuladores como Simics, en sus últimas versiones, soportan hardware de anfitrión multiprocesador y paralelizan eficazmente los núcleos simulados en los núcleos del procesador real.

En cuanto a la velocidad de simulación a nivel de microarquitectura, esto es generalmente de varios órdenes de magnitud, aproximadamente de 1000 a 10000 veces más lento que la ejecución en una computadora normal sin simulación. Y las implementaciones a nivel de elementos lógicos son aún más lentas en varios órdenes. Por lo tanto, se utilizan FPGA como emuladores en este nivel, lo que permite aumentar significativamente el rendimiento.

El gráfico a continuación muestra la relación aproximada entre la velocidad de simulación y el nivel de detalle del modelo.

Simuladores de sistemas informáticos: el conocido simulador de plataforma completa y los poco conocidos modelos por ciclos y rutas.

Simulación por ciclos

A pesar de la baja velocidad de ejecución, los simuladores de microarquitectura son bastante comunes. La modelización de los bloques internos del procesador es necesaria para simular con precisión el tiempo de ejecución de cada instrucción. Aquí puede surgir una confusión, ya que parece que simplemente se podría programar el tiempo de ejecución para cada instrucción. Sin embargo, un simulador de este tipo funcionaría de manera muy imprecisa, ya que el tiempo de ejecución de la misma instrucción puede variar de una llamada a otra.

Un ejemplo simple es la instrucción de acceso a la memoria. Si la celda de memoria solicitada está disponible en la caché, el tiempo de ejecución será mínimo. Si la información necesaria no se encuentra en la caché (un "fallo de caché"), esto incrementará significativamente el tiempo de ejecución de la instrucción. Por lo tanto, se requiere un modelo de caché para una simulación precisa. Sin embargo, el modelo de caché no es lo único a considerar. El procesador no simplemente esperará a recibir los datos de la memoria si no están en la caché. En su lugar, comenzará a ejecutar las siguientes instrucciones, eligiendo aquellas que no dependen del resultado de la lectura de la memoria. Esto se conoce como ejecución "fuera de orden" (OOO, out of order execution), necesaria para minimizar el tiempo de inactividad del procesador. Tener en cuenta todo esto al calcular el tiempo de ejecución de las instrucciones ayudará a modelar los bloques correspondientes del procesador. Entre estas instrucciones, que se ejecutan mientras se espera el resultado de la lectura de la memoria, puede haber una operación de salto condicional. Si el resultado de la condición no es conocido en este momento, el procesador tampoco detiene la ejecución, sino que hace una "suposición", realiza el salto correspondiente y continúa ejecutando de forma preventiva las instrucciones desde el punto de salto. Este bloque, conocido como predecidor de saltos, también debe ser implementado en un simulador de microarquitectura.

La imagen de abajo muestra los bloques principales del procesador; no es necesario conocerla, se presenta únicamente para ilustrar la complejidad de la implementación de la microarquitectura.

Simuladores de sistemas informáticos: el conocido simulador de plataforma completa y los poco conocidos modelos por ciclos y rutas.

El funcionamiento de todos estos bloques en un procesador real se sincroniza con señales de reloj especiales, sucediendo lo mismo en el modelo. A este simulador de microarquitectura se le llama simulación cíclica (cycle accurate). Su principal propósito es prever con precisión el rendimiento del procesador en desarrollo y/o calcular el tiempo de ejecución de un programa específico, como un benchmark. Si los valores resultantes son inferiores a los requeridos, será necesario mejorar los algoritmos y bloques del procesador o optimizar el programa.

Como se mostró anteriormente, la simulación cíclica es muy lenta, por lo que solo se utiliza al investigar ciertos aspectos del funcionamiento de un programa, donde es necesario conocer la verdadera velocidad de ejecución y evaluar el futuro rendimiento del dispositivo cuyo prototipo se está simulando.

Para simular el resto del tiempo de ejecución del programa, se utiliza un simulador funcional. ¿Cómo ocurre realmente este uso combinado? Primero, se inicia el simulador funcional, en el que se carga el sistema operativo y todo lo necesario para ejecutar el programa en estudio. No nos interesa ni el sistema operativo en sí ni las etapas iniciales del inicio del programa, su configuración, etc. Sin embargo, tampoco podemos omitir estas partes y pasar directamente a la ejecución del programa desde la mitad. Por ello, todas estas etapas preliminares se ejecutan en el simulador funcional. Una vez que el programa ha llegado al momento de interés, hay dos opciones. Se puede cambiar al modelo cíclico y continuar la ejecución. El modo de simulación en el que se utiliza el código ejecutable (es decir, archivos de programas compilados) se llama simulación basada en la ejecución (execution driven simulation). Esta es la opción de simulación más común. También es posible otro enfoque: la simulación basada en trazas (trace driven simulation).

Simulación basada en trazas

Consiste en dos pasos. Usando un simulador funcional o en un sistema real, se recopila y registra en un archivo un registro de las acciones del programa. Este registro se llama traza (trace). Dependiendo de lo que se esté investigando, la traza puede incluir instrucciones ejecutables, direcciones de memoria, números de puerto, información sobre interrupciones.

El siguiente paso es la "ejecución" de la traza, cuando el simulador cíclico lee la traza y lleva a cabo todas las instrucciones que contiene. Al final, obtenemos el tiempo de ejecución de este fragmento de programa, así como diversas características de este proceso, como el porcentaje de aciertos en caché.

Una característica importante del trabajo con trazas es la determinación, es decir, al ejecutar la simulación de la forma descrita anteriormente, reproducimos una secuencia de acciones idéntica una y otra vez. Esto permite, al modificar los parámetros del modelo (tamaños de caché, buffers y colas) y utilizando diferentes algoritmos internos o ajustándolos, investigar cómo cada parámetro influye en el rendimiento del sistema y qué opción ofrece los mejores resultados. Todo esto se puede realizar con el modelo prototipo del dispositivo antes de crear un prototipo hardware real.

La complejidad de este enfoque radica en la necesidad de ejecutar previamente la aplicación y recopilar la traza, así como en el gran tamaño del archivo de traza. Entre los aspectos positivos se encuentra que solo es necesario modelar la parte del dispositivo o plataforma que interesa, mientras que la simulación de ejecución generalmente requiere un modelo completo.

Así que en este artículo hemos revisado las características de la simulación de plataforma completa, discutido la velocidad de las implementaciones en diferentes niveles, la simulación cíclica y las trazas. En el siguiente artículo, describiré los principales escenarios de uso de los simuladores, tanto para fines personales como desde la perspectiva del desarrollo en grandes empresas.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster