Architetture dei processori/Architettura Pentium 4

Il Pentium 4 è un processore progettato da Intel quando la strada maestra per aumentare le prestazioni sembrava essere l'innalzamento della frequenza operativa. Il Pentium 4 infatti implementa un'architettura chiamata NetBurst, architettura nata originariamente per spingere il processore fino a frequenze di 10 Gigahertz (in realtà il più veloce Pentium 4 non arriva ai 4 GHz) e difatti dotata di pipeline molto lunghe che possono arrivare fino a 31 stadi con alcuni stadi che servono per trasferire le informazioni tra diverse unità. Pipeline così lunghe subiscono penalizzazioni considerevolmenti elevate in caso di salti non predetti correttamente o in caso di istruzioni devono stallare per la mancanza di qualche risorsa. Per ridurre al minimo il problema il Pentium 4 implementa praticamente tutte le tecniche disponibili per ridurre le condizioni di stallo delle pipeline e implementa internamente più pipeline per sfruttare il parallelismo del codice.

Pentium 4
Pentium 4

Il funzionamento del Pentium 4 può essere riassunto in pochi passaggi fondamentali:

  • Il processore carica le operazioni da eseguire fino ad un massimo di 32.
  • Le operazioni x86 di lunghezza variabile vengono tradotte in microperazioni tipo RISC di lunghezza fissa da 118 bit. Le operazioni x86 possono venir tradotte anche in 4 microoperazioni nel caso delle istruzioni più complesse.
  • Il processore esegue le microoperazioni nelle sue pipeline in modalità fuori ordine per fruttare al massimo il parallelismo interno delle operazioni.
  • I risultati vengono riuniti e trasferiti nel registro corrispondente seguendo l'ordine stabilito dal programma originale.
Architettura del processore

Come si è detto l'obiettivo dell'architettura NetBurst era ottenere frequenza di funzionamento molto elevate e tutto è stato progettato seguendo questo obiettivo. Il processore inizialmente carica i dati, li converte in microoperazioni e li pone in un buffer chiamato Instruction Window, oltre a segnalare le microoperazioni decodificate in un buffer chiamato Trace Buffer che viene utilizzato internamente al processore per la predizione dei salti, la gestione delle eccezioni e per riordinare correttamente i dati dopo che le operazioni sono state eseguite. Le microoperazioni sono operazioni concettualmente di tipo RISC ma sono lunghe ben 118 bit per poter gestire correttamente i molteplici modi di indirizzamento delle operazioni x86. Il processore continua a caricare dati fino a quando l'Instruction Window non è pieno. L'unità di predizione dei salti che è basata su una tabella da 512 elementi che tiene traccia degli ultimi salti e del loro risultato analizza le microoperazioni e decide su eventuali salti. In caso di salto il processore controlla la tabella e se trova che l'istruzione di salto è già stata eseguita in passato si comporta concordemente al contenuto della tabella. In caso di mancanza di dati il processore si basa su una tabella statica. Una singola predizione sbagliata può ridurre le prestazioni del processore del 20%-30% per via delle pipeline molto lunghe. Il processore effettua la ridenominazione dei registri sia per ottenere il massimo parallelismo consentito dall'esecuzione fuori ordine delle istruzioni sia per contrastare i limite dell'architettura x86 che prevede la presenza di soli 8 registri di uso generico. Il processore dispone di 128 registri nascosti che assegna dinamicamente alle varie istruzioni con la ridenominazione dei registri per ridurre i conflitti. Le operazioni vengono divise in due code: una coda raccoglie le operazioni in memoria (Load e Store) e l’altra per tutti gli altri tipi di operazioni. Ogni coda funziona in modalità FIFO (First-In First-Out), ma non esiste alcun tipo di relazione tra l’ordine reciproco delle due code. Appena un'unità funzionale compatibile con un'istruzione libera da conflitti diventa disponibile lo scheduler della coda trasferisce l'istruzione nell'unità funzionale. Gli scheduler sono in grado di allocare fino a sei operazioni elementari per ciclo di clock. Difatti le ALU per le operazioni semplici lavorano a frequenza di clock doppia quindi per ogni ciclo di clock sono in grado di processare quattro istruzioni, le altre due unità funzionali possono eseguire un'operazione a testa e quindi in teoria si possono eseguire fino a sei operazioni per ciclo anche se in realtà questo si verifica molto di rado. Il processore per contrastare i tempi di accesso alla memoria che con frequenza di funzionamento prossime a 4 Gigahertz sono estremamente importanti implementa un meccanismo di precaricamento dei dati. Questo è gestito sia da quattro istruzioni SSE per il codice appositamente compilato, sia tramite un meccanismo di previsione dinamica implementato nel processore che cerca di prevedere in anticipo quale codice andrà caricato. Dopo che le operazioni sono state eseguite l'unità finale provvede ad aggiornare i registri secondo l'ordine del programma originario, va notato che anche le eventuali eccezioni generate dalle istruzioni vengono gestite da questa unità, difatti le eccezioni vanno sollevate solamente quando ordine logico del programma lo prevede e non appena si verificano altrimenti si avrebbe un comportamento non predicibile dei programmi.

Prestazioni modifica

Le prestazioni del Pentium 4 rapportate alla frequenza di funzionamento non sono particolarmente elevate. Il Pentium 4 come si è detto all'inizio è nato per funzionare a frequenze di funzionamento molto elevate. Difatti a parità di frequenza di clock offre prestazioni leggermente inferiori al precedente Pentium 3. L'obiettivo delle altissime frequenze poi è stato solo parzialmente raggiunto dato che limiti tecnologici non previsti inizialmente hanno impedito al processore di arrivare alle frequenze inizialmente previste di 10 Gigahertz. Difatti i successivi processori Intel come i Pentium M sono stati basati su architetture più performanti a parità di frequenza per ottenere prestazioni maggiori e consumi inferiori.