Nell'ambito dell'ingegneria informatica, un'architettura del set di istruzioni[1][2][3] (in inglese: instruction set architecture), abbreviata come ISA, è un modello astratto che definisce in generale il modo in cui il software controlla la CPU di un computer o di una famiglia di computer.[4] Un dispositivo o un programma che esegue le istruzioni descritte da tale ISA, ad esempio un'unità di elaborazione centrale (CPU), è detto implementazione di tale ISA.
In generale, un'ISA definisce le istruzioni supportate, i tipi di dati, i registri, il supporto hardware per la gestione della memoria principale[non chiaro], le caratteristiche fondamentali (come la consistenza della memoria, le modalità di indirizzamento, la memoria virtuale) e il modello di input/output delle implementazioni dell'ISA.
Un'ISA specifica il comportamento del codice macchina in esecuzione sulle proprie implementazioni in un modo indipendente da esse, garantendone la compatibilità binaria. Ciò consente di avere più implementazioni di un'ISA che differiscono per caratteristiche quali le prestazioni, le dimensioni fisiche e il costo, ma che sono in grado di eseguire lo stesso codice macchina, in modo tale che una macchina con prestazioni inferiori e costi inferiori possa essere sostituita con una macchina con prestazioni superiori e costi più elevati, senza la necessità di sostituire il software. Inoltre, l'ISA consente l'evoluzione delle microarchitetture delle sue implementazioni, in modo da garantire la retrocompatibilità, vale a dire che un'implementazione più recente e più performante di una ISA possa eseguire il software che gira sulle generazioni precedenti di implementazioni.
Se un sistema operativo mantiene un'interfaccia binaria dell'applicazione (ABI) standard e compatibile per una particolare ISA, il codice macchina verrà eseguito sulle future implementazioni di tale ISA e sistema operativo. Tuttavia, se un'ISA supporta l'esecuzione di più sistemi operativi, ciò non garantisce che il codice macchina per un sistema operativo (SO) venga eseguito su un altro SO, a meno che il primo non supporti l'esecuzione di codice macchina creato per il secondo.
Un'ISA può essere estesa aggiungendo istruzioni o altre funzionalità, o aggiungendo il supporto per indirizzi e valori di dati più grandi; un'implementazione dell'ISA estesa sarà comunque in grado di eseguire codice macchina per le versioni dell'ISA che non sono estese. Viceversa, il codice macchina che utilizza tali estensioni verrà eseguito solo su implementazioni che le supportano.
La compatibilità binaria che forniscono rende le ISA una delle astrazioni più fondamentali dell'informatica.
Generalità
[modifica | modifica wikitesto]L'architettura del set di istruzioni si distingue dalla microarchitettura, che è l'insieme delle tecniche di progettazione del processore utilizzate per implementare il set di istruzioni in un particolare processore. Processori con microarchitetture diverse possono condividere un set di istruzioni comune. Ad esempio, l'Intel Pentium e l'AMD Athlon implementano versioni quasi identiche del set di istruzioni x86, pur presentando una progettazione interna radicalmente differente.
Il concetto di architettura, distinto dalla progettazione di una macchina specifica, è stato sviluppato da Fred Brooks all'IBM durante la fase di progettazione del System/360:
«Prima dell'NPL (System/360), i progettisti di computer dell'azienda erano stati liberi di rispettare gli obiettivi di costo non solo selezionando le tecnologie, ma anche creando migliorie funzionali e architetturali. L'obiettivo di compatibilità SPREAD, invece, prevedeva un'unica architettura per una serie di cinque processori che coprivano un'ampia gamma di costi e prestazioni. Nessuno dei cinque team di progettazione poteva contare sulla possibilità di apportare modifiche alle specifiche architetturali per attenuare le difficoltà nel raggiungimento degli obiettivi di costo e prestazioni.»
Alcune macchine virtuali che supportano il bytecode del tipo di ISA, come Smalltalk, la macchina virtuale Java e il Common Language Runtime di Microsoft, lo implementano traducendo il bytecode per i percorsi di codice comunemente utilizzati nel codice macchina nativo. Inoltre, queste macchine virtuali eseguono i percorsi di codice usati meno frequentemente per interpretazione (vedi: compilatore just-in-time). Transmeta ha implementato in questo modo il set di istruzioni x86 sui processori VLIW.
Classificazione delle ISA
[modifica | modifica wikitesto]Un'ISA può essere classificata in diversi modi. Una classificazione comune è quella per complessità architetturale. Un computer con set di istruzioni complesso (CISC) è caratterizzato da molte istruzioni specializzate, alcune delle quali possono essere utilizzate solo raramente nella pratica. Un computer a set di istruzioni ridotto (RISC) semplifica il processore implementando in modo efficiente solo le istruzioni generalmente utilizzate nei programmi, mentre le operazioni meno comuni sono implementate come subroutine, con il conseguente tempo di esecuzione aggiuntivo del processore che però è compensato dalla loro rarità.[6]
Altri tipi includono da un lato le architetture VLIW (Very Long instruction word) e le architetture LIW (Long instruction word), strettamente correlate tra loro, e dall'altro le architetture EPIC (explicitly parallel instruction computing). Queste architetture cercano di sfruttare il calcolo parallelo a livello di istruzioni, richiedendo meno hardware di RISC e CISC e rendendo il compilatore responsabile dell'emissione e dello scheduling delle istruzioni.[7]
Sono state studiate architetture con una complessità ancora minore, come il minimal instruction set computer (MISC) e il one-instruction set computer (OISC). Si tratta di tipologie teoricamente importanti, ma che non sono state commercializzate.[8][9]
Istruzioni
[modifica | modifica wikitesto]Il linguaggio macchina è costituito da istruzioni discrete. Sull'architettura di elaborazione, una data istruzione può specificare:
- opcode (l'istruzione da eseguire): aggiungi, copia, testa;
- qualsiasi operando esplicito:
- registri
- valori letterali/costanti
- modalità di indirizzamento utilizzate per accedere alla memoria.
Operazioni più complesse vengono costruite combinando queste istruzioni semplici, che vengono eseguite in sequenza o come altrimenti indicato dalle istruzioni del flusso di controllo.
Tipologie di istruzioni
[modifica | modifica wikitesto]Esempi di operazioni comuni a molti set di istruzioni sono:
Gestione dei dati e operazioni di memoria
[modifica | modifica wikitesto]- impostare un registro su un valore costante;
- copiare dati da una locazione di memoria o da un registro a una locazione di memoria o a un altro registro (un'istruzione macchina spesso chiamata “move”, ma il termine è fuorviante). Vengono utilizzate per memorizzare il contenuto di un registro, il contenuto di un'altra locazione di memoria o il risultato di un calcolo oppure per recuperare i dati memorizzati per eseguire un calcolo successivo. Spesso vengono chiamate operazioni di load-store;
- leggere e scrivere dati da dispositivi hardware.
Operazioni aritmetiche e logiche
[modifica | modifica wikitesto]- aggiungere, sottrarre, moltiplicare o dividere i valori di due registri, collocando il risultato in un registro, eventualmente impostando uno o più codici di condizione in un registro di stato;[10]
- incrementare, decrementare in alcune ISA, risparmiando il fetch degli operandi nei casi banali;
- eseguire operazioni bitwise, ad esempio, prendere la congiunzione logica e la disgiunzione dei bit corrispondenti in una coppia di registri, prendere la negazione di ciascun bit in un registro;
- confrontare due valori nei registri (ad esempio, per vedere se uno è minore o se sono uguali);
- istruzioni in virgola mobile per l'aritmetica sui numeri in virgola mobile.[11]
Operazioni di controllo del flusso
[modifica | modifica wikitesto]- eseguire un fork verso un'altra posizione del programma in cui esegue le istruzioni;
- diramazione condizionale (conditional brunch) verso un'altra posizione se una certa condizione è soddisfatta.
- diramazione indiretta (indirect branch) verso un'altra posizione.
- richiamare un altro blocco di codice, salvando la posizione dell'istruzione successiva come punto di ritorno.
Istruzioni del coprocessore
[modifica | modifica wikitesto]- caricamento/memorizzazione di dati da e verso un coprocessore o scambio con i registri della CPU.
- eseguire operazioni con il coprocessore.
Istruzioni complesse
[modifica | modifica wikitesto]I processori possono includere istruzioni “complesse” nel loro set di istruzioni. Una singola istruzione “complessa” esegue un'operazione che può richiedere molte istruzioni su altri computer. Tali istruzioni sono caratterizzate da istruzioni che richiedono molteplici passaggi, controllano più unità funzionali o appaiono in altro modo su una scala più ampia rispetto alla maggior parte delle istruzioni semplici implementate da un determinato processore. Alcuni esempi di istruzioni “complesse” sono:
- trasferimento di più registri da o verso la memoria (in particolare lo stack) in una sola volta;
- spostamento di grandi blocchi di memoria (ad esempio, copia di stringhe o trasferimento DMA);
- aritmetica complicata in numeri interi e in virgola mobile (ad esempio, radice quadrata o funzioni trascendenti come logaritmo, seno, coseno, ecc.);
- istruzioni SIMD, una singola istruzione che esegue un'operazione su molti valori omogenei in parallelo, eventualmente in registri SIMD dedicati;
- esecuzione di un'istruzione atomica di test-and-set o di un'altra istruzione atomica di lettura-modifica-scrittura;
- istruzioni che eseguono operazioni ALU con un operando dalla memoria piuttosto che da un registro.
Le istruzioni complesse sono più comuni nei set di istruzioni CISC che in quelli RISC, ma anche i set di istruzioni RISC possono includerle. I set di istruzioni RISC generalmente non includono operazioni ALU con operandi di memoria o istruzioni per spostarne grandi blocchi; la maggior parte dei set di istruzioni RISC include istruzioni SIMD o vettoriali che eseguono la stessa operazione aritmetica su più dati contemporaneamente. Le istruzioni SIMD sono in grado di manipolare vettori e matrici di grandi dimensioni in un tempo minimo. Le istruzioni SIMD consentono una facile parallelizzazione degli algoritmi comunemente utilizzati nell'elaborazione di suoni, immagini e video. Sono state introdotte sul mercato diverse implementazioni SIMD con nomi commerciali come MMX, 3DNow! e AltiVec.
Codifica delle istruzioni
[modifica | modifica wikitesto]Nelle architetture tradizionali, un'istruzione comprende un codice operativo che specifica l'operazione da eseguire, ad esempio aggiungere il contenuto della memoria a un registro, e zero o più specificatori di operando, che possono specificare registri, posizioni di memoria o dati letterali. Gli specificatori di operando possono avere modalità di indirizzamento che ne determinano il significato o possono essere in campi fissi. Nelle architetture VLIW (Very Long Instructions Word), che comprendono molte architetture di microcodice, in una singola istruzione vengono specificati più codici operativi e operandi simultanei.
Alcuni set di istruzioni esotiche non hanno un campo opcode, come le architetture con attivazione del trasporto (transport triggered architectures, TTA), ma solo operandi.
La maggior parte delle macchine a pila ha set di istruzioni di tipo “0-operand” (v. sotto) in cui le operazioni aritmetiche e logiche sono prive di campi di specificazione dell'operando; solo le istruzioni che spingono gli operandi sullo stack di valutazione o che popolano gli operandi dallo stack alle variabili hanno specificatori di operando. Il set di istruzioni esegue la maggior parte delle azioni dell'ALU con operazioni postfix (notazione polacca inversa) che operano solo sulla pila delle espressioni, non sui registri di dati o su celle arbitrarie della memoria principale. Questo può essere molto conveniente per la compilazione di linguaggi di alto livello, perché la maggior parte delle espressioni aritmetiche può essere facilmente tradotta in notazione postfissa.[12]
Le istruzioni condizionali hanno spesso un campo predicato, ovvero alcuni bit che codificano la condizione specifica per cui un'operazione deve essere eseguita piuttosto che non eseguita. Ad esempio, un'istruzione di diramazione condizionale trasferisce il controllo se la condizione è vera, in modo che l'esecuzione proceda a una parte diversa del programma, e non trasferisce il controllo se la condizione è falsa, in modo che l'esecuzione continui in modo sequenziale. Alcuni set di istruzioni prevedono anche spostamenti condizionati, in modo che lo spostamento venga eseguito e i dati memorizzati nella posizione di destinazione (se la condizione è vera), mentre non venga eseguito e la posizione di destinazione non venga modificata (se la condizione è falsa). Analogamente, IBM z/Architecture dispone di un'istruzione di memorizzazione condizionale.
Numero di operandi
[modifica | modifica wikitesto]I set di istruzioni possono essere classificati in base al numero massimo di operandi esplicitamente specificati al loro interno.
(Negli esempi che seguono, a, b e c sono indirizzi (diretti o calcolati) che si riferiscono a celle di memoria, mentre reg1 e così via si riferiscono ai registri della macchina).
- C = A+B
- macchine a 0 operandi (macchine a indirizzo zero), le cosiddette macchine a pila (stack machine): tutte le operazioni aritmetiche avvengono utilizzando le prime due posizioni della pila:[13]
push a
,push b
,add
,pop c
- C = A+B necessita di quattro istruzioni.[14] Per le macchine a pila, i termini "o perandi" e "o0 indirizzi" si applicano alle istruzioni aritmetiche, ma non a tutte le istruzioni, poiché le istruzioni
push
epop
a un operando sono utilizzate per accedere alla memoria.
- C = A+B necessita di quattro istruzioni.[14] Per le macchine a pila, i termini "o perandi" e "o0 indirizzi" si applicano alle istruzioni aritmetiche, ma non a tutte le istruzioni, poiché le istruzioni
- le macchine a un solo indirizzo, le cosiddette macchine ad accumulatore, comprendono i primi computer e molti piccoli microcontrollori: la maggior parte delle istruzioni specifica un singolo operando destro (cioè una costante, un registro o una posizione di memoria), con l'accumulatore implicito come operando sinistro (e la destinazione, se esiste):
load a
,add b
,store c
.C = A+B
necessita tre istruzioni'.[15]
- macchine a 2 operandi, categoria in cui ricadono molte macchine CISC e rISC:
- CISC —
muovi A
a C; quindiaggiungi B
a C.C = A+B
necessita di due istruzioni. Effettivamente, memorizza il risultato senza un'istruzione esplicita in tal senso.
- CISC — spesso le macchine sono limitate a un solo operando idi memoria per operazione:
load a,reg1
;add b,reg1
;store reg1,c
; Questo richiede una coppia di caricamento e memorizzazione per qualsiasi movimento di memoria, indipendentemente dal fatto che il risultato dell'istruzioneadd
sia un argomento localizzato in un indirizzo differente, come nel caso diC = A+B
, ovvero nella stessa cella di memoria:A = A+B
.C = A+B
necessita di tre istruzioni.
- RISC - Richiedendo il caricamento esplicito della memoria, le istruzioni sarebbero:
load a,reg1
;load b,reg2
;add reg1,reg2
;store reg2,c
.C = A+B
necessita di quattro istruzioni.
- CISC —
- macchine a 3 operandi, che permettono un migliore recupero dei dati[16]
- CISC- diventa una singola istruzione:
add a,b,c
C = A+B
necessita di una sola istruzione.
- CISC - oppure, su macchine limitate a due operandi di memoria per istruzione:
move a,reg1
;add reg1,b,c
;C = A+B
necessita di due istruzioni.
- RISC _ le istruzioni aritmetiche utilizzano solo i registri, quindi sono necessarie istruzioni di caricamento e memorizzazione esplicite a due operandi:
load a,reg1
;load b,reg2
;add reg1+reg2->reg3
;store reg3,c
;C = A+B
necessita di quattro istruzioni.- diversamente dal caso a 1 e 2 operandi, questo lascia i tre valori (a, b e c) disponibili nei registri per essere utilizzabili successivamente.[16]
- CISC- diventa una singola istruzione:
- alcune macchine CISC a più operandi permettono una varietà di modalità di indirizzamento che consentono più di 3 operandi (registri o accessi alla memoria), come ad esempio l'istruzione VAX “POLY”, istruzione di valutazione polinomiale.
A causa dell'elevato numero di bit necessari per codificare i tre registri di un'istruzione a 3 operandi, le architetture RISC con istruzioni a 16 bit sono invariabilmente progetti a 2 operandi, come Atmel AVR, TI MSP430 e alcune versioni di ARM Thumb. Le architetture RISC con istruzioni a 32 bit sono solitamente progetti a 3 operandi, come le architetture ARM, AVR32, MIPS, Power ISA e SPARC.
Ogni istruzione specifica un certo numero di operandi (registri, posizioni di memoria o valori immediati) in modo esplicito. Alcune istruzioni forniscono uno o entrambi gli operandi in modo implicito, ad esempio memorizzandoli in cima alla pila o in un registro implicito. Se alcuni operandi sono forniti implicitamente, è necessario specificare nell'istruzione un numero inferiore di operandi. Quando un operando specifica esplicitamente la propria destinazione, è necessario fornire un operando aggiuntivo. Di conseguenza, il numero di operandi codificati in un'istruzione può differire dal numero di argomenti matematicamente necessari per un'operazione logica o aritmetica (l'arietà). Gli operandi sono codificati nella rappresentazione “opcode” dell'istruzione, oppure sono forniti come valori o indirizzi dopo l'opcode.
Pressione di registro
[modifica | modifica wikitesto]La pressione dei registri (register pressure) misura la disponibilità di registri liberi in qualsiasi momento durante l'esecuzione del programma. La pressione dei registri è alta quando un gran numero di registri disponibili è in uso; quindi, più alta è la pressione dei registri, più spesso il contenuto dei registri deve essere riversato in memoria. L'aumento del numero di registri in un'architettura diminuisce la pressione dei registri, ma ne aumenta il costo.[17]
Mentre i set di istruzioni embedded come Thumb soffrono di una pressione sui registri estremamente elevata perché hanno insiemi di registri piccoli, le ISA di tipo RISC a scopo generico come MIPS e DEC Alpha godono di una bassa pressione sui registri. Le ISA di tipo CISC come x86-64 offrono una bassa pressione sui registri, nonostante abbiano insiemi di registri più piccoli. Ciò è dovuto alle numerose modalità di indirizzamento e alle ottimizzazioni (come l'indirizzamento ai sottoregistri, gli operandi di memoria nelle istruzioni dell'ALU, l'indirizzamento assoluto, l'indirizzamento PC-relativo e i versamenti da registro a registro) che le ISA CISC offrono.[18]
Note
[modifica | modifica wikitesto]- ^ M. Palesi, Architettura del set di istruzioni (PDF), su diit.unict.it (archiviato dall'url originale il 5 ottobre 2024).
- ^ Università di Ferrara (PDF), su unife.it (archiviato dall'url originale il 4 agosto 2018).
- ^ Prof. Gascia, Università di Catana (PDF), su diit.unict.it (archiviato dall'url originale il 5 ottobre 2024).
- ^ GLOSSARY: Instruction Set Architecture (ISA), su arm.com (archiviato dall'url originale l'11 novembre 2023).
- ^ Emerson W. Pugh, Lyle R. Johnson e John H. Palmer, IBM's 360 and Early 370 Systems, MIT Press, 1991, ISBN 0-262-16123-0.
- ^ Crystal Chen, Greg Novick e Kirk Shimano, RISC Architecture: RISC vs. CISC, su cs.stanford.edu, 16 dicembre 2006 (archiviato dall'url originale il 21 febbraio 2015).
- ^ Michael S. Schlansker e B. Ramakrishna Rau, EPIC: Explicitly Parallel Instruction Computing, in Computer, vol. 33, n. 2, febbraio 2000, pp. 37–45, DOI:10.1109/2.820037.
- ^ Adnan Shaout e Taisir Eldos, On the Classification of Computer Architecture, in International Journal of Science and Technology, vol. 14, estate 2003, p. 3.
- ^ William F. Gilreath e Phillip A. Laplante, Computer Architecture: A Minimalist Perspective, Springer Science+Business Media, 6 dicembre 2012, ISBN 978-1-4615-0237-1.
- ^ Hennessy, John L.; Patterson, David A. (2003). Computer Architecture: A Quantitative Approach (Third ed.). Morgan Kaufmann Publishers. ISBN 1-55860-724-2
- ^ Hennesey, Patterson (2003), p.108
- ^ Paul Durand, Instruction Set Architecture (ISA), in Introduction to Computer Science CS 0.
- ^ Hennessey, Patterson (2003), p. 92
- ^ Hennnessey, Patterson (2003), p. 93
- ^ Hennessy, Patterson (2003), p. 93
- ^ a b The evolution of RISC technology at IBM (PDF), in IBM Journal of Research and Development, vol. 34, n. 1, January 1990, pp. 4–11, DOI:10.1147/rd.341.0004.
- ^ Daniel Page, 11. Compilers, in A Practical Introduction to Computer Architecture, Springer, 2009, p. 464, ISBN 978-1-84882-255-9.
- ^ Harnessing ISA Diversity: Design of a Heterogeneous-ISA Chip Multiprocessor, 41st Annual International Symposium on Computer Architecture, 2014.
Controllo di autorità | GND (DE) 4129931-0 |
---|