# Calcolatori elettronici/Le architetture a pipeline

Calcolatori elettronici
Copertina Tutti i moduli · Sviluppo
    CopertinaCalcolatori elettronici/Copertina
* L'evoluzione dei sistemi di elaborazioneCalcolatori elettronici/L'evoluzione dei sistemi di elaborazione
* Il progetto di circuiti logiciCalcolatori elettronici/Il progetto di circuiti logici
* I processoriCalcolatori elettronici/I processori
* Architettura 8086Calcolatori elettronici/Architettura 8086
* Unità di controlloCalcolatori elettronici/Unità di controllo
* Introduzione alle memorieCalcolatori elettronici/Introduzione alle memorie
* Le memorie ad accesso casualeCalcolatori elettronici/Le memorie ad accesso casuale
* Le memorie cacheCalcolatori elettronici/Le memorie cache
* Le memorie ad accesso serialeCalcolatori elettronici/Le memorie ad accesso seriale
* La memoria virtualeCalcolatori elettronici/La memoria virtuale
* La gestione dei dispositivi input/outputCalcolatori elettronici/La gestione dei dispositivi input/output
* Intel 8255Calcolatori elettronici/Intel 8255
* Intel 8259Calcolatori elettronici/Intel 8259
* I busCalcolatori elettronici/I bus
* Le architetture a pipelineCalcolatori elettronici/Le architetture a pipeline
* Assembler 8086
          IntroduzioneCalcolatori elettronici/Introduzione
   * Informazioni generaliCalcolatori elettronici/Informazioni generali
   * Istruzioni di trasferimento datiCalcolatori elettronici/Istruzioni di trasferimento dati
   * Istruzioni aritmeticheCalcolatori elettronici/Istruzioni aritmetiche
   * Istruzioni per il controllo del flussoCalcolatori elettronici/Istruzioni per il controllo del flusso
   * Istruzioni per la manipolazione dei bitCalcolatori elettronici/Istruzioni per la manipolazione dei bit
   * Le procedureCalcolatori elettronici/Le procedure
   * Istruzioni per il controllo del processoreCalcolatori elettronici/Istruzioni per il controllo del processore
   * Formato delle istruzioni macchina, tempi di esecuzioneCalcolatori elettronici/Formato delle istruzioni macchina, tempi di esecuzione
Modifica il sommario
Per migliorare le prestazioni del processore, oltre ad aumentarne la frequenza, si può modificarne l'architettura.
I processori si differenziano in base al tempo, in termini di colpi di clock, richiesto per il completamento delle istruzioni:
* CISC: (fino agli anni '70) per completare un'istruzione è necessario un certo numero di colpi di clock;
* RISC: (anni '80) completano un'istruzione in un solo colpo di clock;
* superscalari: (anni '90) a ogni colpo di clock completano più di un'istruzione.

## Architettura RISC

I processori con architettura RISC fanno uso delle pipeline.
Nelle istruzioni si possono identificare delle fasi standard (per es. Fetch, Decode, Operate, Write), ciascuna delle quali opera in un solo stadio del processore per colpo di clock → i vari stadi possono essere fatti lavorare in parallelo, così mentre viene completata un'istruzione ce n'è già un'altra a cui manca una fase per il completamento, e il primo stadio inizia a eseguire un'altra istruzione ancora → a ogni colpo di clock viene completata un'istruzione.
Gli stadi sono inframezzati da registri, sincronizzati dallo stesso segnale di clock.

### Instruction set

Il set di istruzioni deve comprendere istruzioni semplici, e le istruzioni devono avere un codice operativo di dimensione regolare in modo che la decodifica sia veloce. C'è un unico modo di indirizzamento, che si basa su un registro e una costante.
Tutte le istruzioni lavorano sui registri, tranne le istruzioni LOAD e STORE che rispettivamente leggono e scrivono tra la memoria e un registro. In questo modo si evitano istruzioni che effettuano accessi pesanti alla memoria. I RISC dispongono di un numero significativo di registri (~100).
Tipicamente l'unità di controllo è cablata e non microprogrammata, grazie al fatto che la gestione dell'unità di elaborazione è più semplice. Un'unità di controllo cablata è inoltre più veloce e più piccola di una microprogrammata.

### Stalli

Tutte le istruzioni devono passare attraverso le stesse fasi; non sono ammessi dei fetch che richiedono più colpi di clock, ma ogni fase deve durare un solo colpo di clock.
Possono verificarsi dei casi imprevedibili, detti stalli, in cui non si fa in tempo a eseguire una fase entro un singolo colpo di clock (ad es. fetch).
I ritardi del fetch possono essere attenuati con una coda delle istruzioni subito dopo la fase di fetch, che normalmente è piena. Se si verifica un miss, lo stadio di decodifica continua a lavorare sulle istruzioni rimaste nella coda.

### Vincoli di dipendenza

Se alcune istruzioni richiedono di operare sul risultato dell'istruzione precedente, oppure le istruzioni in esecuzione in parallelo condividono degli operandi:
* soluzione hardware: il processore aspetta che l'istruzione precedente finisca di accedere al dato condiviso;
* soluzione software: il compilatore aggiunge delle istruzioni NOP → l'hardware è più semplice.

### Istruzioni di salto

Nella pipeline vengono caricate le istruzioni in modo consecutivo → quando l'istruzione di salto scrive il nuovo valore nel PC, l'istruzione consecutiva nel frattempo è già stata caricata in pipeline:
* soluzione software: il compilatore aggiunge delle istruzioni NOP in fase di compilazione;
* soluzione hardware: il processore deve annullare l'esecuzione delle istruzioni in pipeline da saltare.

#### Salti condizionati

I salti condizionati presentano un'ulteriore complicazione, perché non è detto che modifichino il PC.
Già in fase di decodifica dell'istruzione, il processore può tentare di fare una predizione, per evitare il più possibile di caricare inutilmente istruzioni, attraverso opportuni algoritmi basati sull'analisi del codice e/o su statistiche dinamiche calcolate in fase di esecuzione (ad es.: la volta precedente l'istruzione ha saltato?).

### Vantaggi

Un codice ottimizzato per i processori RISC risulta più veloce e di dimensioni comparabili rispetto all'alternativa CISC, perché le istruzioni eseguite nonostante siano in numero maggiore sono più semplici sia in termini di colpi di clock sia in termini di lunghezza in byte. Un codice compilato per un particolare processore RISC però è poco flessibile in termini di compatibilità con altri processori RISC → per questo motivo all'inizio non vennero utilizzati molto in ambito general-purpose ma solo in ambito special-purpose. I processori general-purpose odierni invece usano comunque le pipeline, grazie a dell'hardware che traduce al volo le istruzioni generiche dell'assembler 8086 ad istruzioni più semplici di tipo RISC.
Nei RISC la latenza, ovvero il tempo medio di attesa per il servizio di un interrupt, è molto bassa perché a ogni colpo di clock viene completata un'istruzione.

## Processori superscalari

I processori superscalari usano due pipeline in parallelo per migliorare le prestazioni: a ogni istante sono in esecuzione 8 istruzioni in parallelo. Svantaggio: i vincoli di dipendenza raddoppiano.
Le unità di fetch, decodifica e write-back elaborano due istruzioni per colpo di clock. La fase di operate è svolta da varie unità differenziate a seconda del tipo di istruzione: unità per l'aritmetica intera, unità per l'aritmetica in virgola mobile...

### Completamento non-in-ordine

L'unità di decode diventa un'unità di smistamento (o di issue) che distribuisce le istruzioni sulle varie unità di operate, in modo che tutte le varie unità lavorino il più possibile continuamente → le istruzioni non vengono eseguite nell'ordine in cui compaiono nel codice, ma in parallelo → la coda di completamento usa degli algoritmi che riordinano i risultati e ne garantiscono la correttezza.

## Processori multithread

Non si può aumentare troppo il numero di stadi in parallelo, perché i vincoli di dipendenza sarebbero troppi → si passa dall'Instruction Level Parallelism (ILP) al Thread Level Parallelism (TLP):
* fino agli anni '90, il processore adottava il time sharing, cioè a ogni programma in esecuzione il processore dedicava una parte del tempo, ma in ogni istante eseguiva un solo programma alla volta;
* un processore multithread esegue in parallelo istruzioni provenienti da più programmi in esecuzione → sfruttano al massimo le unità di operate.

## Processori multicore

All'interno dello stesso circuito sono integrati più processori, detti core, su cui viene distribuito il lavoro.