Perché non abbiamo più registri nei microprocessori?


18

I registri non sono teoricamente richiesti; tutti i microprocessori funzionerebbero comunque senza registri. Ma questa aggiunta apparentemente banale ha contribuito a rendere i microprocessori più efficienti.

Perché non possiamo avere più registri per trarne ulteriore vantaggio? Sono solo memoria su chip e si può immaginare che non sia molto difficile aggiungere? Quale fattore ha influenzato il numero di registri per essere quello che sono ora e non, diciamo 10 volte di più?


8
@ Alper91 Molte architetture, ipotetiche e reali, non hanno registri e non è affatto necessario. È semplicemente un'utile ottimizzazione.
pipe

4
Hmm. Nessuno ha menzionato lo Sparc. L'implementazione più grande potrebbe contenere 520 registri (32 finestre per 16 registri, + 8 globali). Li ricordo sicuramente.
Jon

13
Penso che il numero di bit nell'istruzione che è necessario specificare il registro sia un grosso problema. Se hai 1024 registri, allora hai bisogno di almeno 30 bit per ogni istruzione aritmetica - a meno che tu non aggiunga altri vincoli come "tutti e 3 i registri devono appartenere allo stesso gruppo di 32 (nel qual caso hai bisogno di 20 bit).
user253751

8
@pipe - in realtà praticamente qualsiasi progetto pratico richiede "registri" in senso schematico, poiché anche se costruisci una stack machine o qualcosa del genere, devi avere un posto dove tenere gli argomenti sull'ALU, oppure gli output - la maggior parte dei ricordi non ha tre porte di accesso. E una macchina stack ha bisogno di un puntatore stack che è ... un registro! E non menzioniamo i registri della pipeline. Puoi nascondere l'uso di tali "registri" al programmatore, ma ne hai ancora bisogno, e probabilmente quasi quanti ne ha una macchina di registro primitiva.
Chris Stratton,

4
@ChrisStratton Certo, ma fintanto che non sono esposti attraverso l'ISA, è semplicemente un dettaglio di implementazione. Argomento un po 'inutile, dal momento che non sappiamo cosa significhi OP per registro .
pipe

Risposte:


33

Ci sono diversi fattori:

  • le micro-architetture ad alte prestazioni utilizzano la ridenominazione dei registri. Cioè, il numero di registri fisici è superiore al numero di registri architettonicamente visibili e sono in grado di tenere traccia degli usi indipendenti di essi.

  • il raddoppio del numero di registri non raddoppia la prestazione. L'ISTR ( dall'architettura del computer, un approccio quantitativo ) che va dai 16 ai 32 registri porta a un miglioramento del 10% supponendo che l'aumento non abbia effetti negativi (il che è un presupposto molto ottimista).

  • i registri architettonicamente visibili hanno dei costi. Per esempio:

    • Aumentando il loro numero aumenta il numero di bit presi nel formato dell'istruzione per indicare su quale registro si sta agendo (raddoppiare il numero di registro implica avere un altro bit per registro nel formato, impedendo così di usare quei bit per altri usi o forzando una dimensione dell'istruzione più lunga).
    • Aumentare il numero di registri di architettura aumenta il costo di cambio di contesto (poiché devono essere salvati e ripristinati sul cambio di contesto).

1
Scommetto che il miglioramento delle prestazioni dei registri da 16 a 32 dipende totalmente dal potenziale di ottimizzazione del compilatore in questione. Nell'assemblatore, avere accesso al doppio del numero di registri (nell'architettura x64) può migliorare notevolmente le prestazioni, ma solo per ruoli di nicchia e solo se effettivamente utilizzati.
rdtsc,

6
@rdtsc: passare da 8 a 16 registri di architettura offre grandi miglioramenti nella quantità di sversamenti / ricariche per il codice tipico, secondo i dati delle simulazioni in un documento collegato da questa risposta . Influisce sulla dimensione del codice, sul conteggio delle istruzioni e su quanto sia importante l'inoltro di negozi a bassa latenza. 16-> 32 è un effetto molto più piccolo. AFAICT, 16 registri di architettura è una buona scelta per l'hardware con ridenominazione dei registri per rimuovere i pericoli di WAR e WAW.
Peter Cordes,

2
Tuttavia, l'AVX512 di Intel aggiunge altri 16 registri vettoriali, per un totale di 32. (Oltre a raddoppiare la loro larghezza a 64 byte, una linea cache completa). Nascondere la latenza dalle operazioni FP a elevata latenza ad alto rendimento può richiedere molti registri. ad esempio Intel Haswell ha 5c lat, uno per 0,5c throughput FMA, quindi sono necessari 10 accumulatori vettoriali per saturare le unità di esecuzione FMA per una riduzione (ad esempio un prodotto punto o sommando un array, in cui l'FMA fa parte di una dipendenza trasportata da loop ). x86-64 ha solo 16 reg vettoriali. Ma ricorda, numeri interi op, esp. sui registri GP, raramente hanno una latenza superiore a 1c.
Peter Cordes,

1
Il compromesso è diverso per i registri interi, FP e vettoriali. Ad esempio il salvataggio / ripristino pigro dei registri interi non ha senso, farlo per il vettore uno è una scommessa molto migliore. E gli ISA vettoriali hanno spesso più registri di uno intero (AltiVec ne ha almeno fino a 128, ISTR ne ha letti uno su 256 per Sparc ma non riesce a trovare un riferimento ora).
AProgrammer,

1
en.wikipedia.org/wiki/AltiVec ha trentadue registri vettoriali 128b. Mi sono incuriosito di SPARC e ho cercato come funzionava la sua finestra di registro per i cambi di contesto. Ha 32 registri visibili contemporaneamente, ma utilizza una finestra scorrevole su un file di registro più grande. Sembra da questa versione semplificata che il sistema operativo debba conoscere la dimensione dell'intero file di registro della finestra scorrevole per salvarlo / ripristinarlo, perché anche se le istruzioni della finestra scorrevole forniscono memoria per il salvataggio / ripristino dei registri, se necessario, viene eseguito intercettando al sistema operativo.
Peter Cordes,

16

Mentre i registri e la RAM sono entrambi memoria, si accede in modi diversi, per riflettere il costo (nell'area del chip o dei cicli di clock nascosti) di accedervi.

I registri sono strettamente legati all'ALU e possono assumere molti ruoli di origini dati, sink, modificatori, ecc. Hanno quindi bisogno di una vasta gamma di connessioni multiplate. In alcune architetture possiamo scrivere R1 <= R2 + R3, ed è esattamente ciò che accade in un singolo ciclo di clock. Ogni registro è indirizzato direttamente nel codice operativo, questo indirizzamento è una risorsa molto limitata.

Poiché i registri sono costosi da implementare, il numero è generalmente limitato all'ordine del 10/20 nella maggior parte delle architetture.

La RAM è vagamente legata alla CPU, di solito viene canalizzata attraverso una singola connessione condivisa. Ciò rende molto più economico implementare una grande quantità di RAM. Gli indirizzi RAM generalmente provengono da un indirizzo memorizzato nel registro, quindi non consumare una larghezza significativa delle istruzioni.

SPARC è un'architettura interessante, con registri da 64 a 640 a 64 bit, con un contesto di 32 registri che può essere spostato con sovrapposizioni per chiamate di subroutine veloci con passaggio di parametri. Si tende a non trovarli in PC e server in cui i costi contano, come nel 99,999% delle applicazioni.


4
Un altro aspetto è che devi salvare / ripristinare i registri durante un cambio di contesto. Più registri, più tempo.
Michel Billaud,

Vorrei notare che il vecchio TMS9900 conservava tutti i suoi registri di lavoro nella memoria esterna en.wikipedia.org/wiki/Texas_Instruments_TMS9900
Peter Smith

1
Mi ero qualificato "invariabilmente" con (tranne alcune modifiche) ma l'ho tirato fuori per semplificarlo. Forse lo cambierò in 'generalmente'. Fondamentalmente se riesci a trovare e comprendere le eccezioni, non hai bisogno che io le indichi. Se sei abbastanza forte da essere indotto in errore, allora non importa, perché non ti metterà nei guai. TMS9900, che era strano, avevo una 99/4 per i miei peccati in una vita precedente, strana bestia!
Neil_UK,

Itanium ha anche finestre di registro.
Simon Richter,

1
@ChrisStratton: Anche se esiste un precedente per "non puoi usare i registri X e Y" considerato parte di un "ABI" (es. Registri k0 e k1 su mips), è un uso insolito. Certamente ci sono canali di messaggistica nascosti indesiderati / non sicuri tra i processi se il salvataggio / ripristino di questi "registri proibiti ABI" non viene eseguito al cambio di contesto. Cioè, i processi che non dovrebbero essere in grado di comunicare potrebbero essere in grado di farlo archiviando le informazioni nei registri vietati e aspettando i cambi di contesto.
R ..

12

I registri devono essere indirizzati all'interno dell'istruzione. Se ci sono molti registri, l'istruzione è più lunga. Il salvataggio e il ripristino del contenuto dei registri per un servizio di interruzione richiede più tempo se sono presenti molti registri.


5

Come molte altre cose, il numero di registri è un compromesso tra costo, complessità e utilità.

I registri sono implementati come RAM statica multiporta, il che li rende più costosi (area chip) rispetto ad altre opzioni di archiviazione.

Quindi vengono accoppiati al set di istruzioni del processore, aumentando il numero di registri aumenta la complessità del set di istruzioni. Quindi, se vuoi rimanere compatibile con il set di istruzioni, non puoi semplicemente aumentare il numero di registri disponibili nella prossima generazione di processori per aumentare l'efficienza, i programmi non li userebbero.

Il prossimo è di quanti registri hai davvero bisogno? C'è un limite alla loro utilità. Considera di scrivere un algoritmo che esegue alcune operazioni matematiche su 1024 byte, diciamo moltiplicare per 5. Con i conteggi dei registri attuali, si finisce con qualcosa del tipo:

load operand1=5
load address
loop: load operand2=byte1@address
multiply Register1 with Register2
store result
increment address
if address = end goto endLoop
jump loop
endLoop:

Ora se avessi 1024 registri e tutti i dati memorizzati lì, il tuo programma sarebbe simile a:

multiply Register1 with Register2
multiply Register1 with Register3
multiply Register1 with Register4
multiply Register1 with Register5
multiply Register1 with Register6
...

Poiché ognuno di essi è un'istruzione diversa, ognuno di essi deve essere scritto. Quindi la tua memoria di programma necessaria sta esplodendo. Dopo aver realizzato questo, si potrebbe voler introdurre alcune istruzioni come, multiply register1 with register(2 to 256). Ma quando ti fermi, fornisci un'istruzione per tutte le combinazioni?

Quindi forse i numeri che abbiamo attualmente disponibili sono un ottimo compromesso tra costo, complessità e utilità.


1
Penso che il programma multiply Register1 with Register2 multiply Register1 with Register3sia molto irrealistico in quanto i dati devono provenire direttamente o indirettamente dall'esterno del computer, quindi i registri devono essere caricati e i risultati devono essere utilizzati da qualche parte, direttamente o indirettamente, quindi i registri devono essere archiviati. In realtà, un compilatore decente e ottimizzante per un linguaggio di alto livello 'srotolerà' il ciclo del primo programma per creare qualcosa come il secondo programma, ottimizzando l'uso del registro, la latenza della memoria, forse l'occupazione della cache e la velocità di esecuzione.
Bagliore

1
Non sono necessarie molte multiply register1 with register(2 to 256)istruzioni per scopi speciali . Il pipelining migliora significativamente la produttività della CPU, specialmente per semplificare la decodifica e l'esecuzione delle istruzioni. Pertanto, l'effetto di istruzioni complesse e di grande varietà può essere ottenuto utilizzando diverse istruzioni più semplici con un tasso di esecuzione più elevato. Avere un numero maggiore di registri aiuta consentendo al compilatore di generare molte istruzioni indipendenti (quelle che non condividono un registro), che possono essere completate in modo indipendente, migliorando il throughput. Il tuo esempio = più registri sono migliori.
Bagliore

4

I registri sono molto costosi. Molto costoso. Non sono tanto i registri stessi, ma tutte le connessioni da e verso i registri. Supponi di avere un'istruzione reg1 = reg2 + reg3. Per implementarlo rapidamente , è necessario leggere i dati da due registri in un ciclo e scrivere in un altro registro nel secondo ciclo. Ora, se si dispone di un processore in grado di eseguire più istruzioni per ciclo, pronunciare tre istruzioni, è necessario poter leggere i dati da sei registri per ciclo e scrivere i dati in 3 registri. È un pessimo, terribile numero di connessioni molto veloci.

Ovviamente puoi semplicemente usare più transistor. Il problema è: la velocità scende. È necessario più hardware per scegliere tra più registri. Lo spazio per il file di registro aumenta. Tutto ciò rende le cose più lente. Quindi, con la stessa tecnologia, potresti essere in grado di avere 16 registri e funzionare a 2.600 MHz o avere 32 registri e funzionare a 2.400 MHz. Ora i registri aggiuntivi devono compensare un calo significativo della velocità di clock.


2

Quale fattore ha influenzato il numero di registri

- Gerarchia della memoria

Registri, cache, RAM sono tutti implementati con diverse tecnologie di archiviazione.

Diverse tecnologie differiscono in

  1. Tempi di accesso
  2. Costo
  3. Densità

Un esempio: i registri interni presenti in una CPU sono la memoria ad accesso casuale statico , mentre la memoria principale del computer è la memoria ad accesso casuale dinamico

Una cella binaria RAM statica è implementata utilizzando un circuito a 6 transistor mentre una cella binaria RAM dinamica è implementata utilizzando un condensatore e un transistor. Confronto tra SRAM e DRAM

  • La memoria SRAM è molto più veloce della memoria DRAM [Pochi cicli per accedere a SRAM rispetto a DRAM]
  • Il circuito SRAM consuma meno energia della DRAM
  • La DRAM richiede di aggiornare periodicamente ogni bit della memoria, diversamente dalla SRAM
  • SRAM costa più di DRAM
  • SRAM ha una densità inferiore rispetto alla DRAM

Quindi non è una cosa pratica aumentare il numero della memoria veloce, costosa e con meno densità. In effetti, potremmo usarne alcuni e un programma ben scritto memorizzerà i dati usati più frequentemente all'interno di questi registri veloci mentre i dati usati meno frequentemente sono memorizzati nella memoria più lenta.

- Lunghezza dell'istruzione

L'indirizzo dei registri è incluso in un'istruzione, che limita il numero dei registri accessibili in base ai numeri di bit che possono rappresentare l'indirizzo. Ad esempio nell'architettura MIPS l'istruzione di lunghezza a 32 bit contiene solo 5 bit per rappresentare l'indirizzo dei registri accessibili che limita il numero dei registri a 2 5 = 32 registri. L'aumento del numero dei registri richiederebbe un aumento della lunghezza delle istruzioni per includere bit sufficienti che potrebbero accedere a tutti i registri.


2

Se dai un'occhiata al set di istruzioni di un processore, ci sono diversi modi per raggrupparli. Ad esempio, tutte le ADDistruzioni potrebbero essere raggruppate insieme e tutte le XORistruzioni.

All'interno di ciascun gruppo della stessa istruzione, potrebbero esserci versioni che funzionano in memoria o sui registri. È questo sottogruppo che definisce efficacemente il numero di registri che ha il processore.

Come esempio ipotetico a 8 bit, supponiamo che le $Axistruzioni possano essere le ADDistruzioni e $Cxpotrebbero essere le XORistruzioni. Con questo design, sono rimasti solo quattro bit per definire gli operandi!

  • Uno potrebbe avere solo quattro registri di uso generale e utilizzare due bit per definirne uno e due bit per definire l'altro.
  • Oppure, si potrebbe usare il primo bit per distinguere varianti "speciali" e gli altri 3 bit per definire quale degli otto registri operare con l'accumulatore ( $x0potrebbe essere l'accumulatore stesso).
  • Oppure, si potrebbe avere più di questo numero di registri - ma quindi limitare quali registri sono accessibili a quali istruzioni.

Ovviamente, abbiamo superato i set di istruzioni a 8 bit. Tuttavia, questa logica ha contribuito a definire i set di registri in passato: continuerà a farlo in futuro.

MODIFICA (come richiesto)

Dire all'inizio quattro bit sono per l'istruzione: ADD, SUB, XOR, MOV, CMPecc Ci sono 16 possibilità qui. Quindi, per quelle istruzioni in cui il registro-registro ha senso (ad es. ADD Rx,Ry), È necessario specificare Rxe Ry. Supponiamo che i prossimi due bit siano per x, e gli ultimi due siano per y. Così:

ADD R1, R2  =>  'ADD' + 'R1' + 'R2' => $A0 + $04 + $02

Con solo due bit per definire un registro come questo, hai solo spazio per un totale di quattro registri!

Per inciso, noterai che alcune combinazioni di registri non hanno senso. Ad esempio, MOV Rx, Rx(non fa nulla) e SUB Rx, Rx(produce sempre 0). Queste potrebbero diventare istruzioni per casi speciali:

  1. SUB Rx, Rxpotrebbe diventare NOT Rx- un'istruzione per singolo operando.
  2. MOV Rx, Rxpotrebbe diventare MOVun'istruzione che accetta un secondo byte come valore immediato, interpretato come MOV Rx, #$yy.

In questo modo puoi "giocare" con la mappa delle istruzioni, riempiendo i fori per istruzioni altrimenti inutili o prive di senso per fornire un set di istruzioni più ampio per il programmatore. Ma alla fine, il set di istruzioni definisce il set di registri.


Sono ancora confuso, puoi spiegare come sono rimasti solo 4 bit per gli operandi?
Darshan Chaudhary,

Controlla la mia risposta aggiornata
John Burger,

1
IMHO questa risposta sarebbe significativamente migliorata spostando "l' ipotetico esempio assunto un set di istruzioni a 8 bit " all'inizio della domanda. Ho perso tempo cercando di dare un senso a questo, ho concluso che aveva senso solo per un'istruzione a 8 bit, a lunghezza fissa, quindi continuavo a leggere per scoprire che era il caso. IMHO, quel tipo di set di istruzioni non è molto irrilevante nel contesto della domanda; l'intero spazio di indirizzamento potrebbe essere RAM statica strettamente accoppiata. Penso anche che la parte che inizia " Alcune combinazioni di registri non hanno senso ... " non è rilevante per la domanda e potrebbe essere eliminata. I miei $ 0,02
gbulmer

-2

Oggi Intel utilizza migliaia di registri, centinaia per core della CPU. Ma la maggior quantità di dati memorizzati su una CPU è nella cache, che risponde indirettamente alla domanda. La cache è organizzata in strati, con una piccola cache L1 veloce e cache L2 e L3 più lente più lontane. Il file di registro in un certo senso è L0, persino più veloce di L1 ma anche più piccolo. Quindi, potresti aumentare il numero di registri, ma probabilmente li rallenterebbe.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.