Macchine Intermedie e Struttura a livelli dei computer moderni
La differenza di potenza espressiva fra una macchina astratta che vogliamo realizzare
e la macchina che abbiamo a disposizione per tale realizzazione (Macchina Ospite
o HOST) è detta semantic gap.
Per colmare il divario fra la macchina ML e la macchina HOST, si progetta
un'apposita macchina intermedia MI che viene realizzata sulla macchina HOST.
A questo punto la traduzione dei programmi in L avverrà in termini
del linguaggio di MI, e successivamente il programma per MI
cosí ottenuto verrà eseguito tramite interpretazione sulla macchina HOST.
Tornando alla Fig. 1, notiamo che la pura interpretazione e la pura compilazione si hanno nei casi estremi caratterizzati rispettivamente dal fatto che la MI coincida con la macchina ML o la macchina HOST.
Un esempio concreto di applicazione di questo schema si ha per il linguaggio di programmazione
Java. Non necessariamente la realizzazione di ML sulla macchina intermedia deve essere compilativa. Ci possono essere svariati motivi per avere sia ML che la macchina intermedia realizzati entrambi per interpretazione.
Nello sviluppo dei nostri sistemi di calcolo in genere il procedimento descritto
viene generalizzato, portando ad insieme di livelli di macchine astratte che si
frappongono fra la macchina realizzata in hardware e la macchina astratta del
"livello" utente, che potrebbe essere quella corrispondente ad un HLL
o ad un particolare applicativo (per esempio il programma "Office" o il sistema di
gestione utilizzato dalla vostra banca altro non sono che particolari
macchine astratte).
Il livello più basso rappresenta il computer reale e il linguaggio macchina che esso è in grado di eseguire direttamente. Ciascuno dei livelli superiori rappresenta una macchina astratta, i cui programmi devono essere o tradotti in termini di istruzioni di uno dei livelli inferiori (non necessariamente del livello immediatamente al di sotto), o interpretati da un programma che gira su di una macchina astratta di livello strettamente inferiore.
Un tipico computer moderno si può quindi pensare come una serie
di macchine astratte realizzate una sopra l'altra, ciascuna in grado di
fornire funzionalità via via più potenti.
Nello schema non sono rappresentati i livelli sottostanti la logica digitale. Le componenti fondamentali del livello 0 sono le cosiddette porte logiche (GATES): a partire da raggruppamenti di esse si formano i registri e le memorie. Le GATES sono dispositivi elettronici che, pur appartenendo al mondo analogico, costituiscono il ponte verso il mondo digitale, poichè esse tipicamente realizzano funzionalità (Not, And, Or, ...) che sono ben formalizzabili in termini di una teoria discreta nota come Algebra di Boole.
Collezioni di registri e circuiti digitali che realizzano funzionalità
aritmetico-logiche sono alla base del livello 1. Qui troviamo altri elementi
di interesse come il datapath e le strutture che presiedono al suo
controllo.
Il linguaggio del livello 2 è quello cui tipicamente ci si riferisce quando
si parla di linguaggio macchina di un certo computer. In termini tecnici,
questo livello è noto come ISA Level (Istruction Set Architecture Level);
tipiche istruzioni di questo livello sono ADD, MOVE, SUB, ...
Possiamo provare a fornire una definizione di livello microprogrammato nel seguente
modo: il livello 1 di un sistema di calcolo e' un livello di microprogrammazione
nel caso in cui la memoria programmi della macchina astratta realizzata in hw e' contenuta
sullo stesso chip che contiene la realizzazione della maggior parte delle componenti
(CPU) e non e' quindi realizzata, per esempio, nella RAM di Fig.1. Tale memoria programmi
e' estremamente veloce ma di dimensioni ridotte. Quest'ultima caratteristica
impedisce una realizzazione del livello sovrastaste per compilazione (non potremmo memorizzare
la traduzione di programmi anche minimamente complessi), ma
sicuramente ne permette una per interpretazione.
Il livello 3 evidenzia quella caratteristica precedentemente notata di non
coprire del tutto i livelli sottostanti: si tratta del livello del Sistema
Operativo (SO).
La programmazione dei livelli introdotti fino a questo momento è
tipicamente compito di una cerchia ristretta di programmatori (i cosiddetti
sistemisti), poichè si tratta di macchine astratte che sono state ideate non perchè
interessanti in sè, ma in quanto necessarie per riuscire a gestire la
complessità dell'implementazione delle macchine astratte di livello superiore. Ad ogni modo è al livello 5 che entrano in gioco gli HLL: C, Java, C++, Haskell, Prolog, etc... Si tratta del livello più vario, dove troviamo tutte le possibili soluzioni implementative, anche per macchine astratte relative allo stesso linguaggio: ad esempio, esistono varianti sia interpretate che compilate del BASIC.
Come accennato in precedenza l'avvento di Java ha portato alla nascita di un livello
intermedio tra quelli del linguaggio ad alto livello e quello dell'assembly. Infatti
prima di
essere eseguiti, i programmi Java vengono tradotti in bytecode, ovvero nel
linguaggio macchina della Java Virtual Machine (JVM), che è
realizzata mediante interpretazione sui livelli sottostanti; successivamente saranno i
bytecode così ottenuti che verranno eseguiti sulla JVM. Teniamo a precisare ancora una volta che i livelli appena descritti sono solo una tra le infinite possibilita' teoriche di strutturazione a livelli di un sistema di calcolo.
Programmazione delle Macchine Astratte Una programmazione consapevole ed adeguata per una particolare realizzazione di una macchina astratta e' possibile solo se l'utente conosce non solo la struttura della macchina astratta, ma anche quali componenti sono stati realizzati direttamente in hardware, quali emulati, quali interpretati. Infatti, scegliere un modo piuttosto che un altro di realizzare un algoritmo puo' risolversi in un guadagno di prestazioni, dovuto alla maggiore efficienza della realizzazione di alcune componenti della macchina astratta rispetto ad altri. Gia' il fatto che questa sia una affermazione eccessivamente generica (che non fa cioe' riferimento a particolari contesti in cui poter essere utilizzata) dovrebbe insospettirci. L'Informatica e' la metafora della vita e nella vita non si puo' fare alcuna affermazione che sia valida a prescindere da specifici contesti.Ergo, e' possibile che in particolari contesti l'affermazione citata possa esser vera (pensiamo per esempio al caso di programmare una macchina astratta corrispondente al sistema di controllo della temperatura del nocciolo di una centrale atomica; ovviamente bisogna sfruttare al massimo tutte le possibilita' di velocizzare la routine che, identificato un insolito aumento di temperatura, metta in moto tutte le procedure di sicurezza). In generale pero' sappiamo che non esiste solo la velocita' di esecuzione di un programma come unico parametro di valutazione; per esempio c'e' anche la trasportabilita' di un programma. Un programma che abbia buone prestazioni solo perche' fa affidamento si certe caratteristiche della realizzazione della macchina astratta su cui gira, potrebbe avere prestazioni scadentissime su altre realizzazioni della stessa macchina. Questa considerazione e' ancora piu' importante se si considera' come sia sempre piu' rilevante oggi il concetto di codice mobile. In generale quindi dobbiamo dire che nel programmare una macchina astratta dobbiamo far riferimento solo alla sua specifica, non alla sua realizzazione. 1. E' bene tener presente la possibile ambiguita' che potrebbe generare questo nome. La Java Virtual Machine infatti non e' la macchina astratta corrispondente al linguaggio JAVA, bensi' la macchina intermedia per JAVA.
|