Simulatori di sistemi informatici: il noto simulatore multi-piattaforma e gli sconosciuti simulatori di protocollo e rappresentazione grafica.

Nella seconda parte dell'articolo sui simulatori di sistemi informatici, continuerò a parlare in modo semplice e informativo sui simulatori di computer, in particolare sulla simulazione a piattaforma completa, con cui si imbatte più spesso l'utente comune, nonché sul modello a ciclo e sulle tracce, che sono più comuni nei circoli degli sviluppatori.

Simulatori di sistemi informatici: il noto simulatore multi-piattaforma e gli sconosciuti simulatori di protocollo e rappresentazione grafica.

In parte uno Ho spiegato cosa sono i simulatori in generale e i livelli di modellazione. Ora, basandomi su quelle conoscenze, propongo di immergerci un po' più a fondo e parlare della simulazione a piattaforma completa, di come assemblare le tracce, cosa fare con esse e anche sull'emulazione microarchitettonica a ciclo.

Un simulatore a piattaforma completa (full platform simulator), o 'Nessuno è un guerriero da solo'

Se è necessario esplorare il funzionamento di un dispositivo specifico, come una scheda di rete, o scrivere un firmware o un driver per quel dispositivo, è possibile simularlo separatamente. Tuttavia, utilizzarlo isolato dal resto dell'infrastruttura non è molto pratico. Per far funzionare il driver corrispondente sono necessari un processore centrale, memoria, accesso al bus per il trasferimento dei dati e altro ancora. Inoltre, per il funzionamento del driver è necessaria un sistema operativo (SO) e uno stack di rete. Inoltre, potrebbe essere richiesto un generatore di pacchetti separato e un server per ricevere le risposte.

Un simulatore multipiattaforma crea un ambiente per l'esecuzione di un'intera stack software, che comprende tutto, dal BIOS e dal bootloader fino al sistema operativo stesso e a diverse sue sottosistemi, come lo stesso stack di rete, i driver, e le applicazioni di livello utente. Per questo motivo, implementa modelli software della maggior parte dei dispositivi del computer: il processore e la memoria, il disco, le periferiche di input-output (tastiera, mouse, display), così come la scheda di rete.

Di seguito è riportato un diagramma a blocchi del chipset x58 di Intel. In un simulatore completo di computer basato su questo chipset, è necessaria l'implementazione della maggior parte dei dispositivi elencati, compresi quelli all'interno dell'IOH (Input/Output Hub) e dell'ICH (Input/Output Controller Hub), non rappresentati in dettaglio nel diagramma. Tuttavia, come dimostra la pratica, ci sono diversi dispositivi che non vengono utilizzati dal software che intendiamo eseguire. Non è necessario creare modelli di tali dispositivi.

Simulatori di sistemi informatici: il noto simulatore multi-piattaforma e gli sconosciuti simulatori di protocollo e rappresentazione grafica.

Le simulazioni complete sono più comunemente implementate a livello delle istruzioni del processore (ISA, vedi. l'articolo precedente). Это позволяет относительно быстро и недорого создать сам симулятор. Уровень ISA также хорош тем, что остается более или менее постоянным, в отличие от, например, уровня API/ABI, который меняется чаще. К тому же, реализация на уровне инструкций позволяет запускать так называемое немодифицированное бинарное ПО, то есть запускать уже скомпилированный код без каких-либо изменений, ровно в том виде как он используется на реальном железе. Другими словами, можно сделать копию («дамп») жесткого диска, указать его в качестве образа для модели в полноплатформенном симуляторе и – вуаля! – ОС и остальные программы загружаются в симуляторе без всяких дополнительных действий.

Производительность симуляторов

Simulatori di sistemi informatici: il noto simulatore multi-piattaforma e gli sconosciuti simulatori di protocollo e rappresentazione grafica.

Come accennato in precedenza, il processo di simulazione dell'intero sistema, ovvero di tutti i suoi dispositivi, è piuttosto dispendioso in termini di tempo. Se si tenta di implementarlo a un livello molto dettagliato, ad esempio, a livello di microarchitettura o logico, l'esecuzione diventa estremamente lenta. Tuttavia, il livello delle istruzioni è una scelta appropriata e consente al sistema operativo e ai programmi di funzionare a velocità sufficienti per un'interazione confortevole da parte dell'utente.

Qui vale la pena affrontare il tema delle prestazioni dei simulatori. Di solito, queste vengono misurate in IPS (istruzioni al secondo), e 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à di simulazione dipende anche dalle prestazioni del sistema su cui la simulazione stessa è in esecuzione. Pertanto, potrebbe essere più corretto parlare di "riduzione" (slowdown) del simulatore rispetto al sistema originale.

I simulator a piattaforma completa più comuni sul mercato, come QEMU, VirtualBox o VmWare Workstation, offrono prestazioni soddisfacenti. Per l'utente, può risultare persino impercettibile che l'operazione avvenga all'interno di un simulatore. Questo avviene grazie alle speciali funzionalità di virtualizzazione implementate nei processori, agli algoritmi di traduzione binaria e ad altri aspetti interessanti. Questo è tutto un argomento per un articolo separato, ma se dobbiamo semplificare, la virtualizzazione è una capacità hardware dei processori moderni che consente ai simulatori di non simulare le istruzioni, ma di passarle direttamente all'esecuzione sul processore reale, a condizione che le architetture del simulatore e del processore siano simili. La traduzione binaria consiste nella conversione del codice macchina guest in codice host e nella sua successiva esecuzione sul processore reale. Di conseguenza, la simulazione risulta solo leggermente più lenta, da 5 a 10 volte, o spesso funziona alla stessa velocità del sistema reale. Tuttavia, molti fattori influenzano questo aspetto. Ad esempio, se desideriamo simulare un sistema con diverse decine di processori, la velocità diminuirà immediatamente di molteplici ordini di grandezza. D'altra parte, simulatori come Simics nelle ultime versioni supportano hardware host multi-processore e parallelizzano in modo efficace i nuclei simulati sui nuclei del processore reale.

Parlando della velocità della simulazione microarchitetturale, questa è generalmente più lenta di diversi ordini di grandezza, circa 1000-10000 volte, rispetto all'esecuzione su un computer normale, senza simulazione. Inoltre, le implementazioni a livello di elementi logici sono ancora più lente di diversi ordini. Pertanto, per l'emulazione a questo livello si utilizzano le FPGA, che permettono di aumentare significativamente le prestazioni.

Il grafico qui sotto mostra la relazione approssimativa tra la velocità di simulazione e il dettaglio del modello.

Simulatori di sistemi informatici: il noto simulatore multi-piattaforma e gli sconosciuti simulatori di protocollo e rappresentazione grafica.

Simulazione a ciclo

Nonostante la bassa velocità di esecuzione, i simulatori microarchitetturali sono abbastanza diffusi. La modellazione dei blocchi interni del processore è necessaria per simulare con precisione il tempo di esecuzione di ciascuna istruzione. Qui potrebbe sorgere un malinteso: perché non semplicemente programmare il tempo di esecuzione per ogni istruzione? Ma un simile simulatore funzionerebbe in modo molto impreciso, poiché il tempo di esecuzione della stessa istruzione può variare da un invocazione all'altra.

Un semplice esempio è l'istruzione di accesso alla memoria. Se la cella di memoria richiesta è disponibile nella cache, il tempo di esecuzione sarà minimo. Se l'informazione non è presente nella cache (un "cache miss"), ciò aumenterà significativamente il tempo di esecuzione dell'istruzione. Pertanto, per una simulazione accurata è necessaria un modello di cache. Tuttavia, la questione non si limita solo al modello di cache. Il processore non attenderà semplicemente il recupero dei dati dalla memoria in assenza di essi nella cache. Invece, inizierà a eseguire le istruzioni successive, scegliendo quelle che non dipendono dal risultato della lettura dalla memoria. Questo è il cosiddetto esecuzione "non in ordine" (OOO, out of order execution), necessario per minimizzare il tempo di inattività del processore. Considerare tutto ciò nel calcolo del tempo di esecuzione delle istruzioni aiuterà la simulazione dei corrispondenti blocchi del processore. Tra queste istruzioni, eseguite mentre si attende il risultato della lettura dalla memoria, potrebbe esserci un'operazione di salto condizionale. Se al momento il risultato della condizione non è noto, il processore non interrompe l'esecuzione, ma fa un'"ipotesi", esegue il salto corrispondente e continua a eseguire preventivamente le istruzioni dalla posizione del salto. Questo blocco, chiamato branch predictor, deve anche essere implementato nel simulatore di microarchitettura.

L'immagine qui sotto mostra i principali blocchi del processore; non è necessario conoscerli, è stata fornita solo per illustrare la complessità dell'implementazione della microarchitettura.

Simulatori di sistemi informatici: il noto simulatore multi-piattaforma e gli sconosciuti simulatori di protocollo e rappresentazione grafica.

Il funzionamento di tutti questi blocchi in un processore reale è sincronizzato da segnali di clock speciali, e lo stesso avviene nel modello. Un simulatore di microarchitettura del genere è definito 'ciclo preciso' (cycle accurate). Il suo scopo principale è prevedere con esattezza le prestazioni del processore in fase di sviluppo e/o calcolare il tempo di esecuzione di un determinato programma, come ad esempio un benchmark. Se i valori sono inferiori a quelli necessari, sarà necessario migliorare gli algoritmi e i blocchi del processore o ottimizzare il programma.

Come mostrato sopra, la simulazione ciclica è molto lenta, quindi viene utilizzata solo per l'analisi di specifici aspetti del funzionamento del programma, dove è necessario conoscere la reale velocità di esecuzione e valutare le future prestazioni del dispositivo di cui si sta modellando il prototipo.

Per simulare il resto del tempo di esecuzione del programma, si utilizza un simulatore funzionale. Come avviene realmente questo utilizzo combinato? Inizialmente viene avviato il simulatore funzionale, su cui si carica il sistema operativo e tutto il necessario per avviare il programma in esame. Non ci interessa né il sistema operativo stesso, né le fasi iniziali di avvio del programma, la sua configurazione e altro. Tuttavia, non possiamo neppure saltare queste fasi e passare direttamente all'esecuzione del programma a metà percorso. Pertanto, tutte queste fasi preliminari vengono eseguite su un simulatore funzionale. Una volta che il programma è stato eseguito fino al momento di nostro interesse, ci sono due possibilità. Si può passare a un modello basato sui cicli e continuare l'esecuzione. La modalità di simulazione in cui viene utilizzato il codice eseguibile (cioè i normali file compilati delle applicazioni) è chiamata simulazione basata sull'esecuzione (execution driven simulation). Questa è la forma più comune di simulazione. Esiste anche un altro approccio: la simulazione basata sulle tracce (trace driven simulation).

Simulazione basata sulle tracce

Consiste di due fasi. Utilizzando un simulatore funzionale o su un sistema reale, viene raccolto e registrato un file di log delle azioni del programma. Questo log è chiamato traccia. A seconda di ciò che viene analizzato, la traccia può includere istruzioni eseguibili, indirizzi di memoria, numeri di porta e informazioni sulle interruzioni.

Il passo successivo è la "riproduzione" della traccia, in cui il simulatore a ciclo legge la traccia ed esegue tutte le istruzioni in essa registrate. Alla fine otteniamo il tempo di esecuzione di quel segmento di programma, insieme a varie caratteristiche di questo processo, come la percentuale di cache hit.

Una caratteristica importante del lavoro con i tracciati è la determinazione, cioè, eseguendo la simulazione nel modo descritto sopra, riproduciamo la stessa sequenza di azioni più e più volte. Questo consente di esplorare come un determinato parametro influisce sulle prestazioni del sistema modificando i parametri del modello (dimensioni della cache, buffer e code) e utilizzando diversi algoritmi interni o regolando questi ultimi, per verificare quale opzione offre i migliori risultati. Tutto ciò può essere fatto con un modello prototipale del dispositivo prima di creare un prototipo hardware reale.

La complessità di questo approccio risiede nella necessità di eseguire in anticipo l'applicazione e raccogliere il tracciato, oltre alle enormi dimensioni del file di tracciamento. Tra i vantaggi c'è il fatto che è sufficiente simulare solo la parte rilevante del dispositivo o della piattaforma, mentre la simulazione per esecuzione richiede, di solito, un modello completo.

In questo articolo abbiamo esaminato le caratteristiche della simulazione su piattaforma completa, discutendo della velocità di implementazione a diversi livelli, della simulazione ciclica e delle tracce. Nella prossima articolo descriverò i principali scenari di utilizzo dei simulatori, sia per scopi personali sia dal punto di vista dello sviluppo nelle grandi aziende.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster