Simulatori di sistemi informatici: un simulatore familiare a piattaforma completa e sconosciuto in senso orario e tracce

Nella seconda parte dell'articolo sui simulatori di sistemi informatici, continuerò a parlare in una semplice forma introduttiva dei simulatori di computer, in particolare della simulazione a piattaforma completa, che l'utente medio incontra più spesso, nonché del clock-by -modello e tracce dell'orologio, che sono più comuni negli ambienti degli sviluppatori.

Simulatori di sistemi informatici: un simulatore familiare a piattaforma completa e sconosciuto in senso orario e tracce

В la prima parte Ho parlato di cosa sono i simulatori in generale, nonché dei livelli di simulazione. Ora, sulla base di questa conoscenza, propongo di immergermi un po’ più a fondo e parlare della simulazione dell’intera piattaforma, di come raccogliere tracce, cosa farne in seguito, nonché dell’emulazione microarchitettonica orologio per orologio.

Simulatore di piattaforma completa, ovvero "Solo sul campo non è un guerriero"

Se desideri studiare il funzionamento di un dispositivo specifico, ad esempio una scheda di rete, o scrivere firmware o driver per questo dispositivo, è possibile simulare tale dispositivo separatamente. Tuttavia, utilizzarlo separatamente dal resto dell’infrastruttura non è molto conveniente. Per eseguire il driver corrispondente, avrai bisogno di un processore centrale, memoria, accesso a un bus dati, ecc. Inoltre, il driver richiede un sistema operativo (OS) e uno stack di rete per funzionare. Inoltre, potrebbero essere necessari un generatore di pacchetti e un server di risposta separati.

Un simulatore a piattaforma completa crea un ambiente per l'esecuzione di uno stack software completo, che include tutto, dal BIOS e bootloader al sistema operativo stesso e ai suoi vari sottosistemi, come lo stesso stack di rete, driver e applicazioni a livello utente. Per fare ciò, implementa modelli software della maggior parte dei dispositivi informatici: processore e memoria, disco, dispositivi di input/output (tastiera, mouse, display), nonché la stessa scheda di rete.

Di seguito è riportato uno schema a blocchi del chipset x58 di Intel. Un simulatore di computer a piattaforma completa su questo chipset richiede l'implementazione della maggior parte dei dispositivi elencati, inclusi quelli all'interno di IOH (Input/Output Hub) e ICH (Input/Output Controller Hub), che non sono illustrati in dettaglio nel diagramma a blocchi . Sebbene, come dimostra la pratica, non sono molti i dispositivi che non vengono utilizzati dal software che eseguiremo. Non è necessario creare modelli di tali dispositivi.

Simulatori di sistemi informatici: un simulatore familiare a piattaforma completa e sconosciuto in senso orario e tracce

Molto spesso, i simulatori dell'intera piattaforma sono implementati a livello di istruzioni del processore (ISA, vedere sotto). articolo precedente). Ciò consente di creare il simulatore stesso in modo relativamente rapido ed economico. Anche il livello ISA è buono perché rimane più o meno costante, a differenza, ad esempio, del livello API/ABI, che cambia più spesso. Inoltre, l'implementazione a livello di istruzione consente di eseguire il cosiddetto software binario non modificato, ovvero di eseguire codice già compilato senza alcuna modifica, esattamente come viene utilizzato sull'hardware reale. In altre parole, puoi creare una copia ("dump") del tuo disco rigido, specificarla come immagine per un modello in un simulatore a piattaforma completa e voilà! – Il sistema operativo e gli altri programmi vengono caricati nel simulatore senza alcuna azione aggiuntiva.

Prestazioni del simulatore

Simulatori di sistemi informatici: un simulatore familiare a piattaforma completa e sconosciuto in senso orario e tracce

Come accennato poco sopra, il processo di simulazione dell'intero sistema, cioè di tutti i suoi dispositivi, è un'impresa piuttosto lenta. Se implementi tutto questo anche a un livello molto dettagliato, ad esempio microarchitettonico o logico, l'esecuzione diventerà estremamente lenta. Ma il livello di istruzione è una scelta appropriata e consente al sistema operativo e ai programmi di essere eseguiti a velocità sufficienti affinché l'utente possa interagire comodamente con essi.

Qui sarebbe opportuno toccare il tema delle prestazioni del simulatore. Solitamente viene misurato in IPS (istruzioni al secondo), più precisamente in MIPS (milioni di IPS), ovvero il numero di istruzioni del processore eseguite dal simulatore in un secondo. Allo stesso tempo, la velocità della simulazione dipende anche dalle prestazioni del sistema su cui viene eseguita la simulazione stessa. Potrebbe quindi essere più corretto parlare di “rallentamento” del simulatore rispetto al sistema originale.

I simulatori full-platform più comuni sul mercato, come QEMU, VirtualBox o VmWare Workstation, hanno buone prestazioni. Potrebbe non essere nemmeno evidente all'utente che il lavoro è in corso nel simulatore. Ciò avviene grazie alle speciali capacità di virtualizzazione implementate nei processori, algoritmi di traduzione binaria e altre cose interessanti. Questo è tutto un argomento per un articolo a parte, ma in breve, la virtualizzazione è una caratteristica hardware dei moderni processori che consente ai simulatori di non simulare istruzioni, ma di inviarle per l'esecuzione direttamente a un processore reale, se, ovviamente, le architetture di il simulatore e il processore sono simili. La traduzione binaria è la traduzione del codice macchina guest in codice host e la successiva esecuzione su un processore reale. Di conseguenza, la simulazione è solo leggermente più lenta, 5-10 volte, e spesso funziona addirittura alla stessa velocità del sistema reale. Anche se questo è influenzato da molti fattori. Se ad esempio vogliamo simulare un sistema con diverse dozzine di processori, la velocità diminuirà immediatamente di queste decine di volte. D'altra parte, i simulatori come Simics nelle ultime versioni supportano l'hardware host multiprocessore e parallelizzano efficacemente i core simulati sui core di un processore reale.

Se parliamo della velocità della simulazione microarchitettonica, di solito è di diversi ordini di grandezza, circa 1000-10000 volte più lenta dell'esecuzione su un normale computer, senza simulazione. E le implementazioni a livello degli elementi logici sono più lente di diversi ordini di grandezza. Pertanto a questo livello viene utilizzato un FPGA come emulatore, il che può aumentare significativamente le prestazioni.

Il grafico seguente mostra una dipendenza approssimativa della velocità di simulazione dal dettaglio del modello.

Simulatori di sistemi informatici: un simulatore familiare a piattaforma completa e sconosciuto in senso orario e tracce

Simulazione battito per battito

Nonostante la loro bassa velocità di esecuzione, i simulatori microarchitettonici sono abbastanza comuni. La simulazione dei blocchi interni del processore è necessaria per simulare accuratamente il tempo di esecuzione di ciascuna istruzione. Qui potrebbero sorgere malintesi: dopo tutto, sembrerebbe, perché non programmare semplicemente il tempo di esecuzione per ciascuna istruzione. Ma un simulatore di questo tipo risulterà molto impreciso, poiché il tempo di esecuzione della stessa istruzione potrebbe differire da una chiamata all'altra.

L'esempio più semplice è un'istruzione di accesso alla memoria. Se la posizione di memoria richiesta è disponibile nella cache, il tempo di esecuzione sarà minimo. Se questa informazione non è nella cache ("cache miss"), ciò aumenterà notevolmente il tempo di esecuzione dell'istruzione. Pertanto, per una simulazione accurata è necessario un modello cache. Tuttavia, la questione non si limita al modello di cache. Il processore non attenderà semplicemente che i dati vengano recuperati dalla memoria quando non sono nella cache. Inizierà invece ad eseguire le istruzioni successive, scegliendo quelle che non dipendono dal risultato della lettura dalla memoria. Si tratta della cosiddetta esecuzione “out of order” (OOO, out of order Execution), necessaria per ridurre al minimo i tempi di inattività del processore. La modellazione dei blocchi del processore corrispondenti aiuterà a tenere conto di tutto ciò nel calcolo del tempo di esecuzione delle istruzioni. Tra queste istruzioni, eseguite mentre si attende il risultato della lettura dalla memoria, può verificarsi un'operazione di salto condizionato. Se il risultato della condizione è sconosciuto al momento, anche in questo caso il processore non interrompe l'esecuzione, ma fa una "ipotesi", esegue il ramo appropriato e continua a eseguire in modo proattivo le istruzioni dal punto di transizione. Tale blocco, chiamato branch predittor, deve essere implementato anche nel simulatore microarchitettonico.

L'immagine sotto mostra i blocchi principali del processore, non è necessario conoscerli, viene mostrata solo per mostrare la complessità dell'implementazione microarchitetturale.

Simulatori di sistemi informatici: un simulatore familiare a piattaforma completa e sconosciuto in senso orario e tracce

Il funzionamento di tutti questi blocchi in un processore reale è sincronizzato da speciali segnali di clock, e lo stesso accade nel modello. Un simulatore microarchitettonico di questo tipo è chiamato cycle accurato. Il suo scopo principale è prevedere con precisione le prestazioni del processore in fase di sviluppo e/o calcolare il tempo di esecuzione di un programma specifico, ad esempio un benchmark. Se i valori sono inferiori a quelli richiesti, sarà necessario modificare gli algoritmi e i blocchi del processore o ottimizzare il programma.

Come mostrato sopra, la simulazione orologio per orologio è molto lenta, quindi viene utilizzata solo quando si studiano determinati momenti del funzionamento di un programma, dove è necessario scoprire la reale velocità di esecuzione del programma e valutare le prestazioni future del dispositivo il cui il prototipo è in fase di simulazione.

In questo caso, viene utilizzato un simulatore funzionale per simulare il tempo di esecuzione rimanente del programma. Come avviene nella realtà questa combinazione di usi? Per prima cosa viene lanciato il simulatore funzionale, sul quale viene caricato l'OS e tutto il necessario per eseguire il programma in studio. Dopotutto, non siamo interessati al sistema operativo in sé, né alle fasi iniziali di avvio del programma, alla sua configurazione, ecc. Tuttavia, non possiamo nemmeno saltare queste parti e passare immediatamente all'esecuzione del programma dalla metà. Pertanto, tutti questi passaggi preliminari vengono eseguiti su un simulatore funzionale. Dopo che il programma è stato eseguito fino al momento che ci interessa, sono possibili due opzioni. È possibile sostituire il modello con un modello clock per ciclo e continuare l'esecuzione. La modalità di simulazione che utilizza codice eseguibile (ovvero file di programma compilati regolari) è chiamata simulazione guidata dall'esecuzione. Questa è l'opzione di simulazione più comune. È anche possibile un altro approccio: la simulazione guidata dalla traccia.

Simulazione basata su tracce

Si compone di due passaggi. Utilizzando un simulatore funzionale o un sistema reale, un registro delle azioni del programma viene raccolto e scritto in un file. Questo registro è chiamato traccia. A seconda di ciò che viene esaminato, la traccia può includere istruzioni eseguibili, indirizzi di memoria, numeri di porta e informazioni sugli interrupt.

Il passo successivo è “riprodurre” la traccia, quando il simulatore orologio per orologio legge la traccia ed esegue tutte le istruzioni scritte in essa. Alla fine, otteniamo il tempo di esecuzione di questa parte del programma, nonché varie caratteristiche di questo processo, ad esempio la percentuale di risultati nella cache.

Una caratteristica importante del lavoro con le tracce è il determinismo, ovvero eseguendo la simulazione nel modo sopra descritto, riproduciamo più e più volte la stessa sequenza di azioni. Ciò rende possibile, modificando i parametri del modello (cache, buffer e dimensioni della coda) e utilizzando diversi algoritmi interni o ottimizzandoli, per studiare come un particolare parametro influisce sulle prestazioni del sistema e quale opzione fornisce i migliori risultati. Tutto ciò può essere fatto con un modello di dispositivo prototipo prima di creare un prototipo hardware reale.

La complessità di questo approccio risiede nella necessità di eseguire prima l'applicazione e raccogliere la traccia, nonché nell'enorme dimensione del file di traccia. I vantaggi includono il fatto che è sufficiente simulare solo la parte del dispositivo o della piattaforma di interesse, mentre la simulazione mediante esecuzione richiede solitamente un modello completo.

Quindi, in questo articolo abbiamo esaminato le caratteristiche della simulazione a piattaforma completa, abbiamo parlato della velocità delle implementazioni a diversi livelli, della simulazione clock per ciclo e delle tracce. Nel prossimo articolo descriverò i principali scenari di utilizzo dei simulatori, sia per scopi personali che in ottica di sviluppo in grandi aziende.

Fonte: habr.com

Aggiungi un commento