Simulators voor computersystemen: een platte platform simulator die iedereen kent en de minder bekende tactische en race simulators.

In het tweede deel van het artikel over computersystemen simulators zal ik op een eenvoudige en overzichtelijke manier verder vertellen over computersimulaties, met name over full-platform simulatie, waarmee de gewone gebruiker het vaakst in aanraking komt, evenals over de cycle-accurate model en de routes die meer gebruikelijk zijn in de kringen van ontwikkelaars.

Simulators voor computersystemen: een platte platform simulator die iedereen kent en de minder bekende tactische en race simulators.

In het eerste deel Ik heb uitgelegd wat simulators in het algemeen zijn, evenals de niveaus van modellering. Nu stel ik voor om op basis van die kennis iets dieper te duiken en te praten over full-platform simulatie, hoe routes te bouwen, wat je daarna met ze moet doen, en ook over cycle-accurate microarchitecturale emulatie.

Een full-platform simulator (full platform simulator), of 'Eén in het veld is geen strijder'

Als het nodig is om de werking van één specifiek apparaat te onderzoeken, bijvoorbeeld een netwerkkaart, of om firmware of een stuurprogramma voor dit apparaat te schrijven, kan dat apparaat afzonderlijk worden gemodelleerd. Het is echter niet erg handig om het los van de rest van de infrastructuur te gebruiken. Voor het opstarten van het bijbehorende stuurprogramma zijn een centrale verwerkingseenheid, geheugen, toegang tot de bus voor gegevensoverdracht en dergelijke vereist. Daarnaast is voor de werking van het stuurprogramma een besturingssysteem (OS) en netwerkstack nodig. Daarnaast kan een aparte pakketgenerator en een server voor het ontvangen van antwoorden nodig zijn.

Een full-platform simulator creëert een omgeving voor het draaien van de volledige softwarestack, die alles omvat, van BIOS en bootloader tot het besturingssysteem zelf en verschillende subsystems, zoals dezelfde netwerkstack, stuurprogramma's en applicaties op gebruikersniveau. Hiervoor zijn softwaremodellen van de meeste apparaten van de computer geïmplementeerd: processor en geheugen, schijf, invoer-uitvoer apparaten (toetsenbord, muis, beeldscherm), evenals die specifieke netwerkkaart.

Hieronder staat een blokdiagram van de x58-chipset van Intel. In een volwaardige computersimulator op deze chipset is de implementatie van de meeste genoemde apparaten noodzakelijk, inclusief de apparaten die zich binnen de IOH (Input/Output Hub) en ICH (Input/Output Controller Hub) bevinden, die niet gedetailleerd op het blokdiagram zijn weergegeven. Hoewel de praktijk laat zien dat er niet zo weinig apparaten zijn die door de software die we willen uitvoeren, niet worden gebruikt. Modellen van dergelijke apparaten hoeven niet te worden gemaakt.

Simulators voor computersystemen: een platte platform simulator die iedereen kent en de minder bekende tactische en race simulators.

Volwaardige simulators worden meestal op het niveau van de processorinstructies (ISA, zie het vorige artikel) geïmplementeerd. Dit maakt het relatief snel en goedkoop om de simulator zelf te creëren. Het ISA-niveau is ook goed omdat het min of meer constant blijft, in tegenstelling tot bijvoorbeeld het API/ABI-niveau, dat vaker verandert. Bovendien maakt implementatie op het niveau van instructies het mogelijk om zogenaamde niet-gemodificeerde binaire software uit te voeren, dat wil zeggen het starten van al gecompileerde code zonder enige wijzigingen, exact zoals deze op de echte hardware wordt gebruikt. Met andere woorden, het is mogelijk om een kopie (‘dump’) van de harde schijf te maken, deze als afbeelding voor het model in de volwaardige simulator op te geven en - voila! - het besturingssysteem en andere programma's worden zonder enige aanvullende acties in de simulator geladen.

Prestaties van simulators

Simulators voor computersystemen: een platte platform simulator die iedereen kent en de minder bekende tactische en race simulators.

Zoals hierboven al werd vermeld, is het simuleren van het hele systeem, dat wil zeggen al zijn apparaten, een vrij langzaam proces. Als je dit ook op een heel gedetailleerd niveau zou implementeren, bijvoorbeeld op microarchitectonisch of logisch niveau, dan zou de uitvoering extreem langzaam worden. Het niveau van instructies is echter een geschikte keuze en laat besturingssystemen en programma's draaien op snelheden die de gebruiker voldoende comfort bieden tijdens de interactie.

Hier is het gepast om het onderwerp prestaties van simulators aan te snijden. Gewoonlijk wordt dit gemeten in IPS (instructies per seconde), beter gezegd in MIPS (miljoenen IPS), dat wil zeggen het aantal processorinstructies dat de simulator in één seconde uitvoert. Tegelijkertijd hangt de snelheidsafhankelijkheid van de simulatie ook af van de prestaties van het systeem waarop de simulatie zelf draait. Daarom is het misschien correcter om te spreken van een ‘vertraging’ (slowdown) van de simulator vergeleken met het originele systeem.

De meest voorkomende full-platform simulators op de markt, zoals QEMU, VirtualBox of VmWare Workstation, bieden een goede prestatie. Een gebruiker zal mogelijk niet eens merken dat het werk in een simulator plaatsvindt. Dit komt door de speciale virtualisatiecapaciteit die in processors is geïmplementeerd, de algoritmen voor binaire vertaling en andere interessante elementen. Dit is allemaal stof voor een apart artikel, maar heel kort samengevat, virtualisatie is een hardwarecapaciteit van moderne processors die het mogelijk maakt voor simulators om instructies niet te simuleren, maar rechtstreeks aan de echte processor te geven om uit te voeren, mits de architecturen van de simulator en de processor vergelijkbaar zijn. Binaire vertaling is het omzetten van de machinecode van de gast naar de host en de daaropvolgende uitvoering op de echte processor. Het resultaat is dat de simulatie slechts een beetje langzamer is, 5-10 keer, en vaak zelfs met dezelfde snelheid draait als het echte systeem. Hoewel er veel factoren van invloed zijn. Bijvoorbeeld, als we een systeem met meerdere tientallen processors willen simuleren, zal de snelheid onmiddellijk tientallen keren dalen. Aan de andere kant ondersteunen simulators zoals Simics in de laatste versies multi-processor host 'hardware' en parallelle verwerking van gesimuleerde kernen op de kernen van de echte processor.

Als we het hebben over de snelheid van microarchitectuur simulatie, dan is dit meestal enkele ordes van grootte, ongeveer 1000-10000 keer langzamer dan de uitvoering op een normale computer zonder simulatie. Implementaties op het niveau van logische elementen zijn nog eens enkele ordes van grootte langzamer. Daarom worden FPGA's als emulator op dit niveau gebruikt, wat de prestaties aanzienlijk kan verhogen.

De onderstaande grafiek toont de geschatte afhankelijkheid van de simulatietijd van de detaillering van het model.

Simulators voor computersystemen: een platte platform simulator die iedereen kent en de minder bekende tactische en race simulators.

Cycle-accurate simulatie

Ondanks de relatief lage uitvoering snelheid, zijn microarchitecturale simulators vrij wijdverbreid. Het modelleren van de interne blokken van de processor is noodzakelijk om de uitvoeringstijd van elke instructie nauwkeurig te simuleren. Hier kan verwarring ontstaan – waarom gewoon niet de uitvoeringstijd voor elke instructie programmeren? Maar zo'n simulator zou zeer onnauwkeurig werken, omdat de uitvoeringstijd van dezelfde instructie kan verschillen van oproep tot oproep.

Een eenvoudig voorbeeld is de geheugen toegang instructie. Als het gevraagde geheugenadres beschikbaar is in de cache, zal de uitvoeringstijd minimaal zijn. Als deze informatie echter niet in de cache aanwezig is (cache miss), zal dit de uitvoeringstijd van de instructie aanzienlijk verhogen. Voor een nauwkeurige simulatie is daarom een cachemodel nodig. Echter, het stopt niet bij alleen een cachemodel. De processor zal niet simpelweg wachten op gegevens uit het geheugen als deze niet in de cache aanwezig zijn. In plaats daarvan zal het beginnen met het uitvoeren van de volgende instructies, waarbij het instructies kiest die niet afhankelijk zijn van de uitlezing van het geheugen. Dit wordt zogenaamde 'uitvoering buiten volgorde' (out of order execution, OOO) genoemd, wat nodig is om de stilstandtijd van de processor te minimaliseren. Alle factoren in overweging nemen bij het berekenen van de uitvoeringstijd van instructies kan worden geholpen door het modelleren van de bijbehorende processorblokken. Onder deze instructies die worden uitgevoerd terwijl de resultaten van de geheugen uitlezing worden afgewacht, kan een conditionele sprongoperatie voorkomen. Als de uitkomst van de voorwaarde op dat moment onbekend is, stopt de processor opnieuw niet met uitvoeren, maar doet een 'vermoeden', voert de bijbehorende sprong uit en blijft preventief instructies uitvoeren vanaf het sprongpunt. Zo'n blok, dat de 'branch predictor' wordt genoemd, moet ook worden geïmplementeerd in de microarchitecturale simulator.

De afbeelding hieronder toont de belangrijkste blokken van de processor. Je hoeft dit niet te weten; het is alleen gegeven om de complexiteit van de microarchitecturale implementatie te illustreren.

Simulators voor computersystemen: een platte platform simulator die iedereen kent en de minder bekende tactische en race simulators.

De werking van al deze blokken in een echte processor wordt gesynchroniseerd door speciale kloksignalen, en hetzelfde gebeurt in het model. Zo'n microarchitecturale simulator wordt een cyclusnauwkeurige simulator genoemd. Het belangrijkste doel ervan is om de prestaties van de ontwikkelde processor nauwkeurig te voorspellen en/of de uitvoeringstijd van een bepaald programma te berekenen, bijvoorbeeld van een benchmark. Als de waarden onder de noodzakelijke liggen, zullen algoritmen en processorblokken moeten worden aangepast of het programma geoptimaliseerd.

Zoals hierboven werd aangetoond, is cyclusnauwkeurige simulatie zeer traag, daarom wordt deze alleen gebruikt bij het onderzoeken van bepaalde aspecten van de werking van een programma, waar het nodig is om de werkelijke snelheid van program execution te weten en de toekomstige prestaties van het apparaat dat wordt gemodelleerd te evalueren.

Voor de simulatie van de rest van de tijd van de program execution wordt echter een functionele simulator gebruikt. Hoe gebeurt dit gecombineerde gebruik in de praktijk? Eerst wordt de functionele simulator gestart, waarop het besturingssysteem en alles wat nodig is om het onderzochte programma te starten, wordt geladen. Wij zijn immers niet geïnteresseerd in het besturingssysteem, noch in de beginfasen van het opstarten van het programma, de configuratie ervan, enzovoorts. We kunnen echter ook deze delen niet overslaan en direct naar de uitvoering van het programma middenin springen. Daarom worden al deze voorbereidende stappen op de functionele simulator uitgevoerd. Nadat het programma is uitgevoerd tot het moment dat wij interessant vinden, zijn er twee mogelijkheden. Het model kan worden vervangen door een cyclusnauwkeurige simulator en de uitvoering kan worden voortgezet. De simulatiemodus waarbij uitvoerbare code (d.w.z. de normale gecompileerde programmabestanden) wordt gebruikt, wordt uitvoering-gebaseerde simulatie (execution driven simulation) genoemd. Dit is de meest voorkomende vorm van simulatie. Er is ook een andere benadering mogelijk - een simulatie op basis van tracés (trace driven simulation).

Simulatie op basis van tracés

Het bestaat uit twee stappen. Met behulp van een functionele simulator of op een echt systeem wordt een logboek van de acties van het programma verzameld en in een bestand opgeslagen. Dit log wordt een trace genoemd. Afhankelijk van wat er wordt onderzocht, kan de trace uitvoerbare instructies, geheugensadres, poortnummers en informatie over onderbrekingen bevatten.

De volgende stap is het 'afspelen' van de trace, waarbij de cycle-accurate simulator de trace leest en alle instructies die eraan zijn vastgelegd uitvoert. Aan het einde krijgen we de uitvoeringstijd van dit stuk programma, evenals verschillende kenmerken van dit proces, bijvoorbeeld het cache-hitpercentage.

Een belangrijke eigenschap van het werken met traces is determinisme, dat wil zeggen, door de simulatie op de hierboven beschreven manier uit te voeren, reproduceren we keer op keer dezelfde reeks acties. Dit biedt de mogelijkheid om, door modelparameters te veranderen (grootte van de cache, buffers en wachtrijen) en verschillende interne algoritmen te gebruiken of deze aan te passen, te onderzoeken hoe een bepaalde parameter de systeemperformance beïnvloedt en welke variant de beste resultaten oplevert. Al deze stappen kunnen met een prototype van het apparaat worden uitgevoerd voordat een echte hardwareprototyping wordt gemaakt.

De complexiteit van deze aanpak ligt in de noodzaak om de applicatie vooraf uit te voeren en de trace te verzamelen, evenals de enorme bestandsgrootte van de trace. Voordelen zijn dat het voldoende is om slechts het interessante deel van het apparaat of platform te modelleren, terwijl de uitvoering van de simulatie doorgaans een volledig model vereist.

In dit artikel hebben we de kenmerken van full-platform simulatie besproken, evenals de snelheid van implementaties op verschillende niveaus, cycle-accurate simulatie en traces. In het volgende artikel zal ik de belangrijkste scenario's voor het gebruik van simulators beschrijven, zowel voor persoonlijke doeleinden als vanuit het ontwikkelingsperspectief van grote bedrijven.

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster