# Very long instruction word

La Very Long Instruction Word è un'architettura obsoleta di processori. Fu sviluppata basandosi sul parallelismo di istruzione. Si tratta di tecniche rudimentali per eseguire più istruzioni in parallelo. I primi metodi prevedevano la realizzazione di unità di elaborazione di tipo pipeline dati, in queste unità le istruzioni vengono elaborate come fossero in una catena di montaggio.
Un miglioramento fu portato dall'introduzione di più unità di calcolo in parallelo (più pipeline) al fine di ottenere un microprocessore superscalare. Un'ulteriore miglioria è stata l'esecuzione fuori ordine delle istruzioni. Con questa modalità di esecuzione le istruzioni non vengono eseguite secondo l'ordine previsto dal programmatore ma secondo l'ordine che permette al processore di eseguirle in parallelo.
Queste tecniche hanno un fondamentale difetto: incrementano molto la complessità del microprocessore. Per poter eseguire le operazioni in parallelo il microprocessore deve costantemente verificare le dipendenze tra le varie istruzioni e i dati al fine di eseguire correttamente i programmi. Esistono più tipologie di dipendenze, per esempio un'istruzione potrebbe dover elaborare un dato ottenuto, come risultato, da un'altra istruzione e quindi questa non potrebbe essere eseguita prima dell'altra istruzione. I moderni microprocessori dedicano molte risorse al controllo delle dipendenze e all'arrangiare le istruzioni in modo da poterne eseguire il maggior numero possibile in parallelo.
L'approccio VLIW cerca di risolvere il problema utilizzando un'altra strada, invece di eseguire il controllo delle dipendenze e delle istruzioni eseguibili in parallelo durante l'elaborazione questi vengono lasciati al compilatore che le determina in modo statico e include nelle istruzioni dei dati di controllo per il processore. Il compilatore assembla le istruzioni in blocchi di più istruzioni (2 o più), i singoli blocchi vengono ricevuti dal processore che li decodifica e esegue le istruzioni in parallelo senza dover controllare dipendenze o altro, dato che tutto è già stato controllato dal compilatore. Questo permette di semplificare di molto il processore e di ottenere microprocessori molto veloci.

## Progetto

In un processore superscalare il numero di unità di calcolo non è visibile nel set di istruzioni. Ogni istruzione in formato binario codifica una sola istruzione da eseguire, che normalmente è di 32-64 bit o meno.
Invece le istruzioni VLIW vengono raggruppate in bundle, ciascuno dei quali contiene più istruzioni elementari, specificando per ognuna l'appartenenza ad una specifica unità di calcolo. Per esempio un dispositivo VLIW con 5 unità di calcolo sarà dotato di bundles (o istruzioni lunghe) con cinque campi, ciascuno dei quali istruirà un'unità di calcolo. Ovviamente le istruzioni VLIW sono molto più lunghe delle classiche istruzioni: almeno 64 bit, ma spesso sono di 128 bit o più.
Sin dalle prime architetture ci si è resi conto che aggiungendo unità di calcolo alle macchine si potevano incrementare le prestazioni senza aumentare i costi in maniera eccessiva. Nelle CPU superscalari è la CPU stessa che durante l'esecuzione decide dinamicamente quali istruzioni mandare in esecuzione in parallelo, nelle CPU VLIW è il compilatore che durante la fase di traduzione decide quali istruzioni vadano eseguite in parallelo.
In un'istruzione VLIW spetta al compilatore rilevare le dipendenze tra istruzioni e assemblarle in gruppi ottimizzati. Una dipendenza tipica si ha, ad esempio, quando un'istruzione assembly X deve elaborare il risultato di un'altra istruzione Y. In questa circostanza le due non possono venir eseguite in parallelo. Il compilatore VLIW rileva questa dipendenza ed attua politiche di risoluzione dei conflitti. Una politica attuabile potrebbe essere quella di anticipare alcune istruzioni indipendenti. Quando questo non risulta fattibile il compilatore introduce una NOP che stalla l'unità di calcolo. L'assenza della logica che attua lo scheduling dinamico riduce significativamente la complessità, il costo e l'assorbimento energetico della CPU.
Un altro problema si presenta se il risultato di un'istruzione viene utilizzato per definire se uscire da un ciclo o no. Molte CPU moderne scelgono in anticipo un percorso in modo da poter caricare i dati corrispondenti. Alcune CPU sono dotate di un'unità di predizione delle diramazioni che effettua un'analisi del codice per prevedere la diramazione più probabile. Questi metodi incrementano la complessità del progetto e corrompono la filosofia originaria delle architetture RISC anche perché la CPU deve contenere anche l'elettronica che in caso di errore della predizione elimina le istruzioni in esecuzione e elimina le eventuali modifiche già eseguite (undo).
In un'architettura VLIW il compilatore utilizza delle euristiche o dei profili per predeterminare in anticipo il ramo più probabile. Avendo il compilatore molto più tempo della CPU e la possibilità di analizzare tutto il codice e non solo qualche istruzione, le sue previsioni in teoria dovrebbero essere più precise di CPU che lavora in tempo reale. Il compilatore sviluppa il codice inserendo le istruzioni relative al ramo più probabilmente scelto in cascata nel codice, e codifica l'algoritmo necessario per fare l'undo nel caso la previsione non sia quella corretta. È da notare che i microprocessori ad alte prestazioni con unità di predizione delle diramazioni allo stato dell'arte spesso forniscono predizioni delle diramazioni simili se non superiori a quelli forniti statisticamente dai compilatori. Questo perché sebbene l'unità di predizione debba eseguire le sue analisi nel giro di frazioni di nanosecondo è anche vero che l'unità dispone di informazioni in tempo reale sullo stato del processore e queste informazioni indirizzano le predizioni migliorandone la precisione.

## Storia

Dalla fine degli anni sessanta si erano svolti degli studi per realizzare dei sistemi di calcolo che permettessero al programmatore di caricare più istruzioni in parallelo all'interno di un'unità di calcolo. Melliar-Smith nel 1969 in un articolo pubblicato da AFIPS FJCC proposero un primitivo sistema VLIW. Negli anni settanta altri lavori portarono al perfezionamento di questa idea e portarono alla realizzazione di unità come i CDC Advanced Flexible Processor. Queste unità comunque richiedevano una programmazione a basso livello delle unità funzionali per poter sfruttare la capacità di eseguire più istruzioni in parallelo del sistema, questo era un grande limite perché una programmazione parallela a livello di istruzioni è estremamente difficile e tediosa quindi solo pochi programmi sfruttavano efficacemente le potenzialità dei sistemi. All'inizio degli anni ottanta vi furono molti lavori volti allo studio di generici processori con architettura tipo VLIS. Nel 1981 James H. Pomerene per l'IBM depose un brevetto su un sistema di elaborazione parallelo che eseguisse più istruzioni indipendenti raccolte in gruppi. Nello stesso anno Bob Rau pubblicò un lavoro sul Polycyclic Architecture project sullo sviluppo di un sistema VLIW. Nel 1983 Josh Fisher presentò il progetto ELI-512 su un sistema VLIW. Fisher sviluppò la sua architettura VLIW mentre era docente presso l'Università Yale. Fisher sviluppò le tecniche utilizzate dai compilatori per avvantaggiarsi dell'architettura VLIW. L'idea innovativa di Fisher era quella di cercare di rendere il codice parallelo non limitandosi ad analizzare i blocchi elementari di codice (blocchi di codici sequenziali), ma che bisognava estendere l'analisi a tutto il programma o a buona parte di esso. A tal fine sviluppò la trace scheduling una tecnica di analisi del codice che estendeva l'analisi anche a zone di codice soggette a salti condizionati. Il compilatore cercava di prevedere i risultati dei salti condizionati e compilava il codice di conseguenza, il compilatore inseriva anche del codice che in caso di errata predizione eliminava le istruzioni errate. Questo permetteva al compilatore di analizzare ampie porzioni di codice alla ricerca di istruzioni da eseguire in parallelo e quindi migliorava le prestazioni dei processori.
La seconda idea innovativa di Fisher fu di sviluppare insieme il compilatore e il processore. Entrambi erano una parte del progetto complessivo e quindi dovevano suddividersi il lavoro perché un microprocessore troppo complesso sarebbe stato molto lento ma avrebbe richiesto un compilatore semplice, invece un microprocessore troppo semplice avrebbe richiesto un compilatore troppo complesso da programmare e quindi si sarebbero avute comunque prestazioni deludenti pur avendo potenzialmente un microprocessore molto veloce. Fisher sviluppò alcune strutture hardware come self-draining pipeline, ampi registri multiporta e una particolare architettura della memoria al fine di semplificare al compilatore il compito.
Il primo compilatore VLIW venne sviluppato da John Ellis durante la sua tesi di dottorato, tesi supervisionata da Fisher.

## Implementazioni

Nel 1984 Fisher abbandonò Yale per avviare la società Multiflow che fondò con John O'Donnell e John Ruttenberg. La società produsse la serie di minisupercomputer TRACE basati sull'architettura VLIW. Il primo sistema venne messo in commercio nel 1988 ed era in grado di eseguire 28 operazioni in parallelo per istruzione. I sistemi TRACE implementavano un mix di componenti MSI/LSI/VLSI su scheda, dato che per ragioni tecnologiche questo era più economico che integrare tutti i componenti in un solo integrato. La società non riuscì a vendere molti sistemi, perché i continui incrementi dell'elettronica permisero alle società produttrici di microprocessori "classici" di mantenere il passo con le soluzioni VLIW in molti campi; comunque le altre società riconobbero il valore tecnologico dell'idea difatti la Multiflow riuscì a vendere molti brevetti.
Nello stesso periodo (anni ottanta) venne fondata la Cydrome, una società nata per sviluppare processori VLIW con tecnologia ECL. Questa compagnia come la Multiflow abbandonò il mercato dopo alcuni anni, la società era stata fondata da David Yen, Wei Yen e Bob Rau uno dei pionieri dell'architettura VLIW.
Uno dei licenziatari della tecnologia Multiflow fu la Hewlett-Packard, nella quale entrò anche Fisher dopo la fine della Multiflow. Nel 1988 Bob Rau entrò a far parte della società dopo il fallimento della Cydrome, HP acquisì proprietà intellettuali anche dalla Cydrome. I due progettisti lavorarono per la società per tutti gli anni novanta.
Alla HP i due ricercatori studiarono come rendere più efficienti i processori PA-RISC della società. Questi scoprirono che si poteva semplificare di molto il progetto della CPU eliminando la gestione dell'assegnazione delle istruzioni alle unità logiche dal processore e trasferendo il compito al compilatore. I compilatori degli anni novanta erano molto più complessi di quelli utilizzati durante gli anni ottanta e quindi la complessità aggiuntiva era trascurabile.
Le ricerche volte da Rau e Fisher presso l'HP portarono in seguito allo sviluppo dei processori Itanium in collaborazione con Intel.
I processori VLIW trovarono ampia applicazione nel mercato embedded, le famiglie TriMedia di NXP Semiconductors, SHARC DSP di Analog Devices, la famiglia C6000 di Texas Instruments e la famiglia ST200 di STMicroelectronics sono soluzioni VLIW.

## Problematiche

Il principale problema di questa architettura è l'estrema dipendenza dei programmi dal compilatore. Un programma ottimizzato per un processore VLIW per lavorare in modo efficiente sulla generazione successiva di microprocessori va quasi sempre ricompilato. Questo rende problematico per un utente cambiare il computer dato che anche il suo parco software andrebbe adattato al nuovo processore a meno che i programmi non siano scritti con un linguaggio come Java che, appoggiandosi ad un ulteriore strato software (Virtual Machine) per l'esecuzione del byte code generato dal compilatore, possa essere adattato alla macchina durante l'esecuzione. Un'altra strategia è utilizzare uno strato software che interpreti il vecchio codice e lo adatti al nuovo processore ma in questo caso si ha un deperimento delle prestazioni che può essere anche molto marcato. Questa strategia viene utilizzata per esempio dal processore Efficeon della Transmeta che interpreta codice Intel X86 standard e internamente lo traduce in codice VLIW per la CPU.

## Evoluzioni

L'architettura VLIW ha indubbiamente molti vantaggi ma i suoi problemi ne rendono problematico l'utilizzo in processori per computer. La necessità di ricompilare il codice per ogni generazione di processori in particolare si scontra con la necessità degli utenti di poter mantenere il parco software. Per eliminare questi problemi diverse società hanno sviluppato delle evoluzioni dell'architettura VLIW, tra le varie evoluzioni la più famosa è l'architettura EPIC sviluppata da Intel e HP congiuntamente. L'architettura EPIC (explicitly parallel instruction computing) raggruppa le istruzioni elementari in parole come una classica architettura VLIW e inserisce inoltre delle informazioni sul parallelismo tra le varie parole. In questo modo le varie generazioni del processore possono variare internamente la loro architettura senza troppi problemi. Le informazioni sul parallelismo permettono di realizzare unità di decodifica che sfruttano il parallelismo efficientemente ma sono nel contempo semplici dato che l'analisi del codice parallelo e la sua suddivisione è stata effettuata dal compilatore.
Un'altra architettura che può essere considerata un'evoluzione dell'architettura VLIW è l'architettura TRIPS. Questa architettura a differenza delle precedenti architetture richiede anche una radicale modifica del set di istruzioni, difatti questa architettura utilizza un nuovo set di istruzioni chiamato Explicit Data Graph Execution (EDGE). Questo set di istruzioni considera le istruzioni come degli elementi che ricevono dati, li elaborano e li inviano ad altre istruzioni. Quindi le varie istruzioni sono legate dai dati che elaborano. EDGE in sostanza raccoglie le istruzioni che elaborano gli stessi dati in blocchi e le invia al processore. Ogni blocco di istruzioni è collegato agli altri blocchi da un grafo delle dipendenze che viene generato dal compilatore. Questo set di istruzioni permette di sviluppare il processore come tante unità di calcolo che ricevono blocchi di dati e li elaborano in parallelo, le singole unità di calcolo alla fine dell'elaborazione di un blocco possono scambiarsi delle informazioni se necessario. Questo permette di incrementare notevolmente il numero di operazioni eseguite in parallelo dal singolo processore. Quest'architettura tuttavia è attualmente (2009) un progetto di ricerca e non è detto che diventerà un prodotto commerciale.