Simulatoren von Computersystemen: der bekannte Plattform-Simulator und unbekannte Zyklen und Spuren

Im zweiten Teil des Artikels über Computersystem-Simulatoren werde ich weiterhin in einer einfachen Einarbeitungsform über Computersimulatoren sprechen, nämlich über Vollplattform-Simulationen, auf die ein gewöhnlicher Benutzer am häufigsten stößt, sowie über das Beat-Modell und die Tracks, die unter Entwicklern häufiger vorkommen.



Bild



Im ersten Teil habe ich darüber gesprochen, was Simulatoren im Allgemeinen sind, sowie über Simulationsebenen. Basierend auf diesem Wissen schlage ich nun vor, etwas tiefer zu tauchen und über die Simulation einer vollständigen Plattform, das Zusammenstellen von Spuren, was später damit zu tun ist sowie die zyklische Mikroarchitekturemulation zu sprechen.



Vollplattformsimulator oder "Allein auf dem Feld - kein Krieger"



Wenn Sie den Betrieb eines bestimmten Geräts untersuchen müssen, z. B. einer Netzwerkkarte, oder eine Firmware oder einen Treiber für dieses Gerät schreiben müssen, kann ein solches Gerät separat modelliert werden. Es ist jedoch nicht sehr praktisch, es isoliert vom Rest der Infrastruktur zu verwenden. Um den entsprechenden Treiber auszuführen, benötigen Sie einen Zentralprozessor, Speicher, Zugriff auf den Bus für die Datenübertragung usw. Darüber hinaus benötigt der Treiber ein Betriebssystem und einen Netzwerkstapel. Zusätzlich kann ein separater Paketgenerator und Antwortserver erforderlich sein.



Ein Vollplattform-Simulator erstellt eine Umgebung zum Starten eines vollständigen Software-Stacks, der alles vom BIOS und dem Bootloader bis zum Betriebssystem selbst und seinen verschiedenen Subsystemen umfasst, z. B. denselben Netzwerkstack, dieselben Treiber und dieselben Anwendungen auf Benutzerebene. Zu diesem Zweck werden Softwaremodelle der meisten Computergeräte implementiert: Prozessor und Speicher, Festplatte, Eingabe- / Ausgabegeräte (Tastatur, Maus, Display) sowie dieselbe Netzwerkkarte.



Unten sehen Sie ein Blockdiagramm des x58-Chipsatzes von Intel. In einem Vollplattform-Computersimulator auf diesem Chipsatz müssen die meisten der aufgelisteten Geräte implementiert werden, einschließlich der Geräte im IOH (Input / Output Hub) und ICH (Input / Output Controller Hub), die im Blockdiagramm nicht detailliert dargestellt sind. Obwohl es, wie die Praxis zeigt, nicht so wenige Geräte gibt, die von der Software nicht verwendet werden, werden wir sie starten. Modelle solcher Geräte müssen nicht erstellt werden.



Bild



In den meisten Fällen werden vollständige Plattformsimulatoren auf Prozessoranweisungsebene (ISA, siehe vorherigen Artikel) implementiert). Auf diese Weise können Sie den Simulator selbst relativ schnell und kostengünstig erstellen. Das ISA-Niveau ist auch gut, weil es mehr oder weniger konstant bleibt, im Gegensatz zum Beispiel zum API / ABI-Niveau, das sich häufiger ändert. Darüber hinaus können Sie mit der Implementierung auf Befehlsebene die sogenannte unmodifizierte Binärsoftware ausführen, dh den bereits kompilierten Code unverändert ausführen, genau wie er auf realer Hardware verwendet wird. Mit anderen Worten, Sie können eine Kopie ("Dump") Ihrer Festplatte erstellen, diese als Image für ein Modell in einem Vollplattform-Simulator angeben und voila! - Betriebssystem und andere Programme werden ohne zusätzliche Aktionen in den Simulator geladen.



Simulatorleistung





Bild



Wie oben erwähnt, ist der Prozess der Simulation des gesamten Systems, dh aller seiner Geräte, eine ziemlich langsame Übung. Wenn Sie all dies auch auf einer sehr detaillierten Ebene implementieren, z. B. mikroarchitektonisch oder logisch, wird die Ausführung extrem langsam. Die Ebene der Anweisungen ist jedoch eine geeignete Wahl und ermöglicht es dem Betriebssystem und den Programmen, mit einer Geschwindigkeit zu arbeiten, die ausreicht, damit der Benutzer bequem mit ihnen interagieren kann.



Hier ist es nur angebracht, auf das Thema Simulatorleistung einzugehen. Sie wird normalerweise in IPS (Anweisungen pro Sekunde) gemessen, genauer gesagt in MIPS (Millionen IPS), dh der Anzahl der vom Simulator pro Sekunde ausgeführten Prozessorbefehle. Gleichzeitig hängt die Simulationsgeschwindigkeit auch von der Leistung des Systems ab, auf dem die Simulation selbst ausgeführt wird. Daher ist es möglicherweise korrekter, von einer „Verlangsamung“ des Simulators im Vergleich zum ursprünglichen System zu sprechen.



Die gängigsten Vollplattform-Simulatoren auf dem Markt, dieselbe QEMU, VirtualBox oder VmWare Workstation, weisen eine gute Leistung auf. Dem Benutzer fällt möglicherweise nicht einmal auf, dass die Arbeit im Simulator ausgeführt wird. Dies ist auf die spezielle Virtualisierungsfunktion zurückzuführen, die in Prozessoren, binären Übersetzungsalgorithmen und anderen interessanten Dingen implementiert ist. Dies ist alles ein Thema für einen separaten Artikel, aber kurz gesagt, Virtualisierung ist eine Hardwarefunktion moderner Prozessoren, die es Simulatoren ermöglicht, Anweisungen nicht zu simulieren, sondern zur Ausführung direkt an einen realen Prozessor zu senden, wenn natürlich die Architekturen des Simulators und des Prozessors ähnlich sind. Die binäre Übersetzung ist die Übersetzung des Gastmaschinencodes in den Hostcode und die anschließende Ausführung auf einem realen Prozessor. Infolgedessen ist die Simulation alle 5-10 Mal nur geringfügig langsamer.und arbeitet oft im Allgemeinen mit der gleichen Geschwindigkeit wie das reale System. Dies wird zwar von vielen Faktoren beeinflusst. Wenn wir beispielsweise ein System mit mehreren zehn Prozessoren simulieren möchten, sinkt die Geschwindigkeit sofort um das Zehnfache. Andererseits unterstützen Simulatoren wie Simics in neueren Versionen Multiprozessor-Host-Hardware und parallelisieren simulierte Kerne effektiv mit den Kernen eines echten Prozessors.Simulatoren wie Simics in den neuesten Versionen unterstützen Multiprozessor-Host-Hardware und parallelisieren simulierte Kerne effektiv mit realen Prozessorkernen.In neueren Versionen unterstützen Simulatoren wie Simics Multiprozessor-Host-Hardware und parallelisieren simulierte Kerne effektiv mit Kernen eines realen Prozessors.



Wenn wir über die Geschwindigkeit der Mikroarchitektur-Simulation sprechen, dann ist sie normalerweise mehrere Größenordnungen, ungefähr 1000-10000 Mal, langsamer als die Ausführung auf einem normalen Computer ohne Simulation. Und Implementierungen auf der Ebene logischer Elemente sind um mehrere Größenordnungen noch langsamer. Daher wird FPGA auf dieser Ebene als Emulator verwendet, was die Leistung erheblich steigern kann.



Die folgende Grafik zeigt die ungefähre Abhängigkeit der Simulationsgeschwindigkeit von Modelldetails.



Bild



Taktweise Simulation



Trotz der geringen Ausführungsgeschwindigkeit sind Mikroarchitektur-Simulatoren weit verbreitet. Die Simulation der internen Blöcke des Prozessors ist notwendig, um die Ausführungszeit jedes Befehls genau zu simulieren. Hier kann ein Missverständnis auftreten - schließlich scheint es, warum nicht einfach die Ausführungszeit für jede Anweisung nehmen und programmieren. Ein solcher Simulator funktioniert jedoch sehr ungenau, da die Ausführungszeit desselben Befehls von Aufruf zu Aufruf unterschiedlich sein kann.



Das einfachste Beispiel ist eine Speicherzugriffsanweisung. Wenn der angeforderte Speicherort im Cache verfügbar ist, ist die Ausführungszeit minimal. Wenn sich keine solchen Informationen im Cache befinden ("Cache-Miss", Cache-Miss), erhöht dies die Ausführungszeit des Befehls erheblich. Daher wird ein Cache-Modell für eine genaue Simulation benötigt. Das Geschäft ist jedoch nicht auf das Cache-Modell beschränkt. Der Prozessor wartet nicht nur darauf, dass Daten aus dem Speicher empfangen werden, wenn sie sich nicht im Cache befinden. Stattdessen beginnt er mit der Ausführung der folgenden Anweisungen und wählt diejenigen aus, die unabhängig vom Ergebnis des Lesens aus dem Speicher sind. Dies ist die sogenannte Out-of-Order-Ausführung (OOO), die erforderlich ist, um Ausfallzeiten des Prozessors zu minimieren. Die Simulation der entsprechenden Prozessorblöcke hilft dabei, all dies bei der Berechnung der Ausführungszeit von Anweisungen zu berücksichtigen. Unter diesen Anweisungen, die ausgeführt werden,Während auf das Ergebnis des Lesens aus dem Speicher gewartet wird, kann eine bedingte Verzweigungsoperation auftreten. Wenn das Ergebnis der Bedingung im Moment unbekannt ist, stoppt der Prozessor erneut nicht die Ausführung, sondern macht eine "Annahme", führt den entsprechenden Übergang durch und führt weiterhin proaktiv Anweisungen vom Übergangspunkt aus aus. Ein solcher Block, der als Verzweigungsprädiktor bezeichnet wird, muss auch in einem Mikroarchitektur-Simulator implementiert werden.



Das Bild unten zeigt die Hauptblöcke des Prozessors. Es ist nicht erforderlich, dies zu wissen. Es wird nur gezeigt, um die Komplexität der Implementierung der Mikroarchitektur zu zeigen.



Bild



Der Betrieb all dieser Einheiten in einem realen Prozessor wird durch spezielle Taktsignale synchronisiert, ähnlich wie im Modell. Dieser Mikroarchitektur-Simulator wird als zyklusgenau bezeichnet. Sein Hauptzweck besteht darin, die Leistung des zu entwickelnden Prozessors genau vorherzusagen und / oder die Ausführungszeit eines bestimmten Programms zu berechnen, beispielsweise eines Benchmarks. Wenn die Werte niedriger als erforderlich sind, müssen die Algorithmen und Prozessorblöcke verfeinert oder das Programm optimiert werden.



Wie oben gezeigt, ist die tickweise Simulation sehr langsam, daher wird sie nur verwendet, wenn bestimmte Momente des Programms untersucht werden, in denen Sie die tatsächliche Geschwindigkeit der Programmausführung ermitteln und die zukünftige Leistung des Geräts bewerten müssen, dessen Prototyp modelliert wird.



In diesem Fall wird ein Funktionssimulator verwendet, um den Rest der Programmlaufzeit zu simulieren. Wie kommt es tatsächlich zu dieser kombinierten Nutzung? Zunächst wird ein Funktionssimulator gestartet, auf den das Betriebssystem und alles, was zum Ausführen des untersuchten Programms erforderlich ist, geladen werden. Schließlich interessieren uns weder das Betriebssystem selbst noch die ersten Phasen des Starts eines Programms, seine Konfiguration usw. Wir können diese Teile jedoch auch nicht überspringen und direkt von der Mitte zur Ausführung des Programms übergehen. Daher werden alle diese vorbereitenden Schritte auf einem Funktionssimulator ausgeführt. Nachdem das Programm zum für uns interessanten Zeitpunkt ausgeführt wurde, gibt es zwei mögliche Optionen. Sie können das Modell zyklisch durch ein Modell ersetzen und die Ausführung fortsetzen. Simulationsmodus, in dem ausführbarer Code verwendet wird (d. H. Regelmäßig kompilierte Programmdateien),wird als ausführungsgesteuerte Simulation bezeichnet. Dies ist die häufigste Simulationsoption. Ein anderer Ansatz ist ebenfalls möglich - die spurgesteuerte Simulation.



Spurbasierte Simulation



Es hat zwei Schritte. Mit einem Funktionssimulator oder auf einem realen System wird ein Protokoll der Programmaktionen gesammelt und in eine Datei geschrieben. Ein solches Protokoll wird als Trace bezeichnet. Je nachdem, was untersucht wird, kann der Trace ausführbare Anweisungen, Speicheradressen, Portnummern und Informationen zu Interrupts enthalten.



Der nächste Schritt besteht darin, den Trace "abzuspielen", wenn der Cycle-by-Clock-Simulator den Trace liest und alle darin geschriebenen Anweisungen ausführt. Am Ende erhalten wir die Ausführungszeit dieses Programmteils sowie verschiedene Merkmale dieses Prozesses, z. B. den Prozentsatz der Treffer im Cache.



Ein wichtiges Merkmal der Arbeit mit Spuren ist der Determinismus, dh wenn die Simulation auf die oben beschriebene Weise gestartet wird, reproduzieren wir immer wieder dieselbe Abfolge von Aktionen. Dies ermöglicht es, durch Ändern der Parameter des Modells (Größe des Caches, der Puffer und Warteschlangen) und Verwenden verschiedener interner Algorithmen oder durch Optimieren dieser zu untersuchen, wie sich ein bestimmter Parameter auf die Systemleistung auswirkt und welche Option die besten Ergebnisse liefert. All dies kann mit dem Prototypmodell des Geräts durchgeführt werden, bevor ein echter Hardware-Prototyp erstellt wird.



Die Komplexität dieses Ansatzes liegt in der Notwendigkeit, die Anwendung vorab auszuführen und den Trace zu erfassen, sowie in der großen Dateigröße mit dem Trace. Zu den Pluspunkten gehört die Tatsache, dass es ausreicht, nur den Teil des Geräts oder der Plattform zu simulieren, der von Interesse ist, während für die Simulation der Ausführung in der Regel ein vollständiges Modell erforderlich ist.



In diesem Artikel haben wir die Funktionen der Vollplattformsimulation untersucht und über die Geschwindigkeit der Implementierung auf verschiedenen Ebenen, die zyklische Simulation und die Traces gesprochen. Im nächsten Artikel werde ich die wichtigsten Szenarien für die Verwendung von Simulatoren sowohl für persönliche Zwecke als auch für die Entwicklung in großen Unternehmen beschreiben.



All Articles