Reduced instruction set computer (RISC), nell'elettronica digitale, indica un'architettura per microprocessori che predilige lo sviluppo di un'architettura semplice e lineare. Questa semplicità di progettazione permette di realizzare microprocessori in grado di eseguire il set di istruzioni in tempi minori rispetto a una architettura CISC.

I più comuni processori RISC sono AVR, PIC, ARM, DEC Alpha, PA-RISC, SPARC, MIPS, RISC-V, POWER e PowerPC.

Evoluzione storica Il contesto prima dell'introduzione All'inizio dell'industria dell'informatica i compilatori non esistevano ed i programmatori scrivevano direttamente in codice macchina o in assembly. Per facilitare il lavoro dei programmatori, i progettisti dei processori decisero di inserire nel set di istruzioni dei processori delle istruzioni anche molto complesse in modo da simulare le funzioni ad alto livello dei linguaggi di programmazione direttamente nei processori. Sempre al fine di facilitare lo sviluppo dei programmi, il set di istruzioni dei microprocessori permetteva dei metodi di indirizzamento dei dati complessi che consentivano di manipolare direttamente i dati in memoria, senza passare dai registri dei microprocessori. Questo non era in realtà possibile dato che il processore può elaborare solo dati contenuti nei registri (il Texas Instruments TMS9900 è un'eccezione), e quando il programmatore utilizzava questi metodi di accesso alla memoria il processore provvedeva a copiare il dato in un registro (a volte un registro riservato) per eseguire l'operazione e successivamente salvare il dato in memoria.

Un altro vantaggio dell'avere un set di istruzioni molto complesso è l'occupazione di memoria. Istruzioni molto complesse consentono di realizzare programmi compatti e all'inizio dell'informatica la memoria era una risorsa molto costosa. Ecco perché i processori avevano molte istruzioni e utilizzavano codifiche a lunghezza variabile di bit per definire le istruzioni in modo da massimizzare la densità di istruzioni.

Le CPU erano dotate di pochi registri per due motivi fondamentali: Realizzare i registri nei processori era molto costoso, in quanto i bit all'interno di un processore costano molto più dei bit memorizzati dalla memoria principale; realizzare molti registri avrebbe richiesto molti transistor e questo avrebbe richiesto di sacrificare le altre unità funzionali del processore. Molti registri richiedono molti bit per essere indirizzati, quindi richiedono più memoria per l'immagazzinamento delle istruzioni.

Questi motivi spinsero i progettisti a realizzare istruzioni con metodi di accesso alla memoria molto complesse, per esempio erano comuni istruzioni in grado di caricare due dati, sommarli e poi salvare il risultato in memoria tutto utilizzando una sola istruzione. Un'altra versione della stessa istruzione caricherebbe i dati dalla memoria, li sommerebbe e salverebbe il dato in un registro per esempio. Una terza variante caricherebbe i dati dalla memoria e da un registro, eseguirebbe la somma e salverebbe i dati in un registro. I processori dotati di molte istruzioni di questo tipo vengono definiti processori CISC.

L'obiettivo principale di allora era realizzare processori che fossero in grado di eseguire operazioni con ogni possibile modo di indirizzamento. La possibilità di utilizzare memorie e registri come ingresso o uscita con le varie combinazioni era chiamata ortogonalità delle istruzioni. Sebbene questo complicasse la realizzazione dei processori si riteneva che velocizzasse i programmi dato che il programmatore poteva di volta in volta utilizzare il comando migliore a seconda del programma che stava scrivendo.

L'idea e la progettazione

Verso la fine degli anni 70, ricercatori dell'IBM e di progetti analoghi dimostrarono che la maggior parte dei modi di indirizzamento non veniva utilizzato nei programmi. Questo era dovuto alla diffusione dei compilatori che, sostituendosi all'ottimizzazione a basso livello applicata dai programmatori, ignoravano i modi di indirizzamento più potenti per concentrarsi su quelli semplici. I compilatori di allora erano in grado di gestire solo le caratteristiche più semplici dei processori anche perché, all'epoca, la teoria dei compilatori era solo agli inizi. Comunque il mercato si stava muovendo con rapidità verso l'utilizzo sempre più massiccio dei compilatori, dato che i linguaggi ad alto livello permettevano di realizzare programmi con rapidità riusando il codice in modo efficiente.

Gli studi dimostrarono che molte istruzioni esotiche venivano utilizzate molto raramente e a volte erano più lente del codice scritto con le istruzioni generiche. L'esempio classico era l'istruzione INDEX dei VAX: questa istruzione era più lenta di un loop implementato con le istruzioni comuni.

In quel periodo la velocità delle CPU e delle memorie era simile, ma era evidente l'incremento di velocità delle prime e pertanto in futuro si avrebbe avuto un divario sempre maggiore tra le due. Per ridurre il problema i progettisti pensarono di includere più registri e cache nei processori in modo da ridurre gli accessi alla memoria; i registri e la cache richiedevano molto spazio e allora si cercò di recuperare spazio riducendo la complessità dei processori.

Studi effettuati da informatici come Andrew Tanenbaum dimostrarono che le CPU prodotte allora erano molto sovradimensionate rispetto alle reali esigenze dei programmi. Tanenbaum dimostrò che il 98% delle costanti in un programma poteva essere memorizzato con parole di 13 bit sebbene la maggior parte delle CPU utilizzasse parole a multipli di 8 bit (8, 16, 24, ecc.) e quindi sprecassero spazio. Questi studi suggerirono di memorizzare le costanti nei bit non utilizzati del set di istruzioni, riducendo il numero degli accessi alla memoria; le costanti non verrebbero caricate dalla memoria o dai registri ma sarebbero state inglobate direttamente nel codice binario dell'istruzione rendendo la CPU più veloce ed efficiente. Tuttavia questo approccio richiedeva istruzioni con codifiche corte e una lunghezza di parola di almeno 32 bit per poter aver a disposizione uno spazio ragionevole per le costanti.

Dato che nelle applicazioni reali la maggior parte del tempo viene dedicata all'esecuzione di operazioni molto semplici, i ricercatori si concentrarono su queste operazioni comuni cercando di rendere la loro esecuzione il più veloce possibile. Visto che la massima velocità di funzionamento delle unità era limitata dal tempo necessario ad eseguire le istruzioni più lente e i modi di indirizzamento più esotici, si decise di eliminare le istruzioni e i modi di indirizzamento poco usati in modo da ottenere un set di istruzioni più snello contenente solo quelle istruzioni che effettivamente venivano richieste e che potevano essere ottimizzate per essere eseguite rapidamente, spesso in un solo ciclo di clock.

L'obiettivo di ridurre le istruzioni portò all'ideazione del nome reduced instruction set computing (lett. "elaborazione con insieme di istruzioni ridotto"): un numero ridotto di istruzioni con metodi di accesso semplici e lineari che permetteva l'utilizzo di soluzioni di tipo pipeline dati. L'utilizzo di pipeline permette di realizzare microprocessori in grado di eseguire la maggior parte delle istruzioni in un ciclo di clock. In un'architettura CISC è molto più difficile includere una pipeline dato che i molteplici metodi di indirizzamento complicano nettamente il funzionamento dell'unità e perciò a parità di potenza di calcolo, un'architettura CISC a pipeline richiede molti più transistor di una architettura RISC a pipeline più significative di quella monoistruzione del CISC a 8 bit 6502.

L'acronimo RISC ha portato spesso dei fraintendimenti. Molti, leggendo «insieme di istruzioni ridotto», pensarono ad un insieme menomato, inadeguato a eseguire con semplicità programmi complessi. Invece i processori RISC moderni sono spesso dotati di un set di istruzioni molto completo, ma non forniscono metodi di indirizzamento esotici o istruzioni utilizzate raramente. Ispirati dalla filosofia RISC, sono state sviluppate macchine basate su set di istruzioni minimali come le MISC, le OISC e le transport triggered architecture, mentre alcune ricerche si sono mosse verso il Turing tarpit.

L'approccio RISC ha il grande vantaggio della velocità ma il suo principale svantaggio è l'occupazione di memoria da parte del codice. Essendo presenti solo istruzioni relativamente semplici, il codice scritto per macchine RISC tende ad essere più grande del codice scritto per macchine CISC.

Le prime evoluzioni Nel frattempo, gli ingegneri trovarono alcuni metodi e tecnologie migliori per incrementare la capacità dei processori senza aumentare la frequenza. All'inizio degli anni 1980 era diffusa l'idea che l'architettura avesse raggiunto il suo limite teorico di velocità. Si riteneva che nuovi incrementi di prestazioni si sarebbero ottenuti solamente grazie ai miglioramenti nei materiali semiconduttori o all'aumento di frequenza. Permettendo transistori più compatti, avrebbero permesso di innalzare la frequenza di funzionamento. Molti sforzi furono rivolti verso il calcolo parallelo e verso metodi di collegamento rapidi. Inoltre, il divario tra la velocità dei processori e delle memorie aumentava, perciò i progettisti iniziarono a studiare tecnologie che riducessero gli accessi alla memoria e aumentassero la velocità dei processori; tuttavia queste tecnologie erano molto difficili da implementare con metodi di accesso alla memoria complessi.

Le prime novità si registrarono nella progettazione di nuove pipeline dati. In una pipeline l'istruzione viene suddivisa in sotto operazioni elementari, che vengono svolte in sequenza dalle unità funzionali disposte come una catena di montaggio. Un normale processore ha una singola unità generica che preleva un'istruzione, la decodifica, carica gli operandi, esegue l'operazione vera e propria e salva il risultato. Queste fasi vengono svolte in modo sequenziale da un processore classico; un processore dotato di pipeline esegue invece queste operazioni in parallelo, dato che, come in una catena di montaggio, possiede più unità specialistiche, ognuna delle quali esegue una singola fase, incrementando in misura notevole le prestazioni.

Altra strategia per incrementare le prestazioni era la creazione di più unità funzionali che lavorassero in parallelo. Per esempio un processore con due unità aritmetiche può lavorare in parallelo su due istruzioni di somma raddoppiando le prestazioni. Questa replicazione delle unità funzionali combinate con le pipeline portò alla realizzazione di processori superscalari in grado di eseguire più di un'operazione per ciclo di clock. Queste nuove idee avevano lo svantaggio di richiedere molti transistor per essere implementate.

I RISC furono inizialmente avvantaggiati dalla semplicità di progetto, e il parco dei transistor lasciava molto spazio libero nel processore per poter implementare queste tecniche. I CISC, invece, con la loro architettura più complessa, si trovarono ad implementare con maggior difficoltà queste idee, anche perché il loro ampio set di istruzioni, e i molti modi di indirizzamento rendevano più complesso implementare una pipeline rispetto a un classico processore RISC. I primi RISC avevano prestazioni inferiori agli equivalenti CISC, ma i processori RISC colmarono presto il divario e all'inizio degli anni 90 superavano i processori CISC praticamente in ogni campo. Oltre a considerazioni di carattere prestazionale, il fatto di dedicare pochi transistor al core vero e proprio del processore permetteva al progettista di un processore RISC un approccio molto flessibile.

Con i molti transistor liberi si poteva per esempio: Aumentare il numero di registri presenti Incrementare il parallelismo interno del processore Aumentare la dimensione della cache Aggiungere altre funzionalità come la gestione dell'I/O o di timer