In elettronica register windows è una tecnica utilizzata per incrementare le prestazioni di operazioni particolarmente comuni come le chiamate alle subroutine (o procedure). Affrontando direttamente a livello hardware i problemi derivati dalle chiamate alle procedure si ottiene un sicuro incremento delle prestazioni dei computer. La risoluzione a livello hardware del problema è una caratteristica distintiva del progetto Berkeley RISC che in seguito è stata utilizzata dai processori commerciali SPARC, AMD 29000 e Intel i960 e dall'architettura EPIC.
Descrizione
[modifica | modifica wikitesto]La maggior parte delle architetture dei processori includono delle piccole zone di memoria molto veloci chiamate registri. I registri vengono utilizzati dal processore per memorizzare gli operandi da elaborare e i risultati, inoltre questi vengono utilizzati per memorizzare lo stato del processore. La presenza di molti registri migliora notevolmente le prestazioni dei processori ma essendo i registri una caratteristica legata al set di istruzioni il loro numero non può essere alterato senza alterare il set di istruzioni del processore e quindi la compatibilità con i programmi passati.
La presenza di molti registri porta però anche degli inconvenienti. Quando si ha una chiamata a una nuova procedura, questa necessiterà di memorizzare i propri dati nei registri, e dato che alcuni registri saranno occupati dai dati precedenti, il processore dovrà salvare lo stato dei registri nella memoria principale perdendo molto tempo. Definire in fase di programmazione/compilazione l'allocazione ottima dei registri è estremamente difficile quindi normalmente i programmatori ignorano il problema lasciando l'incombenza al compilatore che realizza un'ottimizzazione spesso molto approssimativa.
La register window cerca di ovviare al problema. Dato che ogni procedura si aspetta di avere i registri a sua completa disposizione la register window fornisce un insieme di registri indipendenti ad ogni procedura. In sostanza ogni procedura vede solo un sottoinsieme dei registri totali del processore e quando c'è una chiamata a una subroutine il processore commuta ad un insieme di registri liberi e quindi il cambio di contesto è praticamente istantaneo dato che non richiede accessi alla memoria. Quando la chiamata alla subroutine termina vengono resi visibili i registri della procedura principale e i registri utilizzati dalla subroutine vengono segnalati come liberi. Questa tecnica può essere utilizzata più volte in modo da gestire subroutine che chiamano altre subroutine in modo annidato.
Il progetto Berkeley RISC rendeva visibili solo 8 registri dei 64 effettivamente disponibili e quindi il processore poteva gestire con il metodo dello scambio fino a otto chiamate annidate. I progettisti fissarono il limite ad 8 chiamate dato che analisi statistiche dimostrarono che la maggior parte dei programmi utilizzavano 6 chiamate annidate. Nel caso di programmi che utilizzino più di 8 chiamate annidate il processore provvede a salvare i registri in memoria perdendo in prestazioni ma consentendo un funzionamento corretto del programma in ogni condizione.
Per confronto l'architettura SPARC della Sun Microsystems fornisce quattro insiemi di registri ed ogni insieme contiene otto registri. Tre set di otto registri sono utilizzati insieme per creare la finestra (window). Otto registri (da i0 a i7) sono utilizzati per memorizzare i dati di ingresso della procedura corrente. Otto registri (da L0 a L7) sono utilizzati per memorizzare i dati intermedi della procedura e altri otto (da o0 a o7) sono utilizzate per i dati da passare alla procedura successiva. Quando si ha una chiamata alla procedura successiva la finestra scorre di sedici registri, oscurando i registri di ingresso e quelli dei dati intermedi. I registi contenenti i dati di uscita diventano i registri dei dati di ingresso. Infine esistono otto registri globali (da g0 a g7), visibili a tutte le procedure ed utilizzati per passare parametri globali.
L'AMD 29000 ha migliorato il progetto supportando finestre di dimensione variabile in modo da evitare lo spreco di registri nel caso comune che non tutti gli 8 registri siano realmente utilizzati dalla procedura. Inoltre il processore forniva 64 registri globali e 128 da utilizzare per la register window.
La register window inoltre ha il vantaggio che non è direttamente legata al set di istruzioni e quindi può essere espansa senza problemi di compatibilità con il passato. Per esempio i linguaggi di programmazione ad oggetti generano molte chiamate a subroutine e quindi possono penalizzare molto i processori dotati di register window poco profonde. Con questi linguaggi è conveniente incrementare il numero delle finestre da 8 a 16 almeno in modo da trattare direttamente la maggior parte delle chiamate a subroutine. Questo è l'approccio seguito dalla famiglia SPARC che nelle ultime generazioni ha aumentato il numero delle window.
La register window non è l'unico approccio per migliorare la gestione dei registri. Il gruppo della Stanford University che sviluppò i processori MIPS analizzò la soluzione sviluppata da Berkeley e decise che il problema non derivava dal numero insufficiente di registri ma dal loro uso non corretto. Il gruppo di Stanford dedicò molto tempo all'ottimizzazione dei compilatori in modo da migliorare la gestione dei registri da parte dei programmi. La mancanza di register window ha reso il progetto del processore più semplice e pur avendo solo 32 registri nel caso di procedure che facessero uso di molti dati forniva prestazioni migliori del progetto di Berkeley che aveva solo 8 registri per procedura. Infine con i moderni compilatori spesso i processori MIPS offrono prestazioni migliori dei processori SPARC anche nel cambio di contesto.