APX: la nuova architettura di Intel – 8 – Conclusioni

Siamo in chiusura e ne approfitto per riportare qui di seguito l’elenco degli articoli di questa serie:

APX: la nuova architettura di Intel – 1 – Introduzione

APX: la nuova architettura di Intel – 2 – Innovazioni

APX: la nuova architettura di Intel – 3 – Nuove istruzioni

APX: la nuova architettura di Intel – 4 – Vantaggi & pecche

APX: la nuova architettura di Intel – 5 – Densità di codice

APX: la nuova architettura di Intel – 6 – Costi implementativi

APX: la nuova architettura di Intel – 7 – Miglioramenti possibili

Raggiunti i RISC (?)

Come avevo anticipato all’inizio del primo articolo, il cambiamento che APX porta è epocale e, a mio modesto avviso, certamente paragonabile a quello dell’introduzione, da parte di AMD, di x64 quale nuova architettura che ha esteso la ben più famosa x86. Le innovazioni e le modifiche sono tali e così pervasive da trovarci di fronte a una vera e propria nuova architettura, sebbene Intel l’abbia presentata soltanto come un’estensione (e avendo cura di integrarla perfettamente all’esistente ecosistema x64, in maniera del tutto retrocompatibile).

Non penso di esagerare se affermo che i CISC, di cui x86 e x64 sono celeberrimi membri, da tempo immemore siano oggetto di scherno e dileggio per l’esiguo numero di registri che, in genere, hanno messo a disposizione rispetto ai più rinomati e blasonati RISC.

In realtà si tratta di critiche che non hanno alcun fondamento, poiché non esiste una definizione di CISC la quale affermi che debba avere pochi registri e, viceversa, una di RISC la quale asserisca che debba averne molti. Si tratta, infatti, soltanto di mere constatazioni sul fatto che chip etichettati come tali presentino dette caratteristiche, ma non si può, da ciò, assumere che la situazione sia e debba essere sempre ed esattamente la stessa per qualunque membro di queste due macrofamiglie.

Non voglio dilungarmi sull’argomento, in quanto riserverò le mie analisi e riflessioni alla prossima serie sull’atavica diatriba su RISC vs CISC, che metterà in chiaro il tutto dal punto di vista sia tecnico sia storico (il contesto è e rimane molto importante), con l’intento di mettere una pietra tombale sulla questione (posto che i fatti abbiano ancora un qualche valore).

Tornando ad APX, Intel “chiude il cerchio” nonché il divario che la separava da altri produttori di processori grazie all’estensione dei registri general-purpose da 16 a 32. Più registri sono senz’altro una comodità, poiché consentono di ridurre le richieste di lettura e scrittura verso la memoria, sebbene un CISC come x86/x64 ne abbia molta meno necessità rispetto a un RISC, in quanto molte delle sue istruzioni sono in grado di accedere direttamente alla memoria, mentre altre sono anche in grado di caricare o utilizzare valori immediati anche di notevole dimensione (senza, quindi, dover utilizzare apposite istruzioni di caricamento e “sporcare” altri registri allo scopo).

Ciò che conta, in ogni caso, è che con questi 16 registri addizionali cade un altro tabù, sebbene ci sia un prezzo da pagare. Prezzo che è principalmente a carico della progettazione primigenia di un processore (l’8086) che ha costretto all’utilizzo dei famigerati prefissi per poter accedere a questi nuovi registri, aumentando, però, la lunghezza delle istruzioni che ne fanno uso e, di conseguenza, impattando (negativamente) sulla densità di codice (com’è accaduto anche passando da x86 a x64: circa 0,8 byte in più, in media, per ogni istruzione).

Intel ha dichiarato, invece, nella presentazione di questa nuova estensione/architettura, che i risultati sarebbero similari a x64 (in una simulazione preliminare, usando l’arcinoto benchmark SPEC2017). Cosa che suona decisamente strana, in base all’analisi dell’utilizzo dei prefissi in diversi scenari comuni che ho fornito in un precedente articolo. Dubbio che si risolverà con la disponibilità dei nuovi processori che integreranno APX e dei relativi binari che ne faranno uso.

Le istruzioni ternarie

Un’altra caratteristica che è stata per lungo tempo motivo di biasimo per x86/x64 è stata l’assenza di istruzioni ternarie (aventi due sorgenti da cui attingere i dati da utilizzare per l’operazione, e una destinazione in cui conservarne il risultato). Carenza che è stata in parte mitigata quando sono state introdotte alcune nuove istruzioni che sfruttano il prefisso VEX3 (cioè quelle SIMD), ma che comunque è rimasta nelle istruzioni più comuni / general-purpose ed utilizzate (ADD, SUB, AND, ecc.).

Discorso analogo con le istruzioni unarie (NOT, NEG, INC, ecc.), le quali hanno dovuto utilizzare lo stesso operando per specificare sia la sorgente per i dati da elaborare sia la destinazione del risultato.

Intel ha posto rimedio a entrambe le croniche carenze, consentendo di estendere le istruzioni esistenti (non tutte, purtroppo: soltanto alcune sono quelle privilegiate, per le quali è possibile utilizzare questo nuovo meccanismo) in modo da poter specificare un altro argomento (il registro di destinazione). Ed è andata anche ben oltre, consentendo di specificare un operando in memoria per una qualunque delle due sorgenti.

Un netto miglioramento che rende l’architettura non soltanto più flessibile, ma anche più veloce (grazie al fatto di poter eseguire “più lavoro utile” per le istruzioni che traggono vantaggio delle innovazioni apportate), come sembra emergere dai benchmark preliminari.

Ed è utile ribadirlo ulteriormente: si tratta di una funzionalità di cui si sentiva la mancanza da tempo, e che adesso può essere finalmente utilizzata e apprezzata.

Il peso del dell’eredità di 8086 (e successori)

Come ho già affermato parlando dei vantaggi e delle pecche, queste due sono le innovazioni più significative (le altre, a mio avviso, sono di minor importanza nonché portata), che però lasciano l’amaro in bocca a causa dell’approccio utilizzato: estendere con l’n-esima “pezza” (il nuovo prefisso REX2, unito ai cambiamenti apportati all’esistente EVEX) l’esistente architettura x64, la quale con APX si complica ulteriormente.

L’8086 è stato il capostipite di questa famosissima famiglia di processori, ma quando è nato (ben 45 anni fa) non si poteva immaginare quale sarebbe stata la sua storia né era intuibile l’enorme impatto che i microprocessori avrebbero avuto nella tecnologia e nello sviluppo della nostra stessa società. Per cui, quando s’è trovata a far i conti con la concorrenza, Intel ha dovuto rimettere mano al progetto, estendendolo in qualche modo, ma con l’obiettivo di preservare sempre la compatibilità col software esistente (pallino che è stato anche il suo marchio di fabbrica).

Estensioni che sono arrivate a suon di “pezze”, per l’appunto, andando a cercare “buchi” (byte non utilizzati) nella tabella degli opcode, in modo da sfruttarli per aggiungere nuove istruzioni o prefissi, a seconda di cosa servisse. E’ così che sono nati l’80286 e l’80386 in primis (perché sono i processori che hanno portato i cambiamenti più radicali all’ISA).

Purtroppo questa è una mentalità comune che rilevo negli ingegneri che abbiano a che fare con la progettazione delle architetture dei processori e in particolare quando si tratta di estendere quella di un’ISA già esistente: sfruttare qualche buco, lasciato libero da qualche parte, in modo da implementare una certa nuova funzionalità divenuta necessaria.

Non ci sono, purtroppo, molti segnali di un pensiero creativo volto a definire progetti originali, con soluzioni innovative e, magari, “eleganti” atte a risolvere determinate problematiche. Forse è anche una questione di tempo (il famigerato time to market), ma realizzare processori non è cosa che si porti a compimento nel giro di poche settimane.

Il che viene dimostrato anche dall’ultimo articolo in cui ho proposto dei cambiamenti per migliorare l’implementazione di APX: un lavoro che ha richiesto giusto qualche giorno di riflessione, ma che porta notevoli vantaggi. Non serviva, insomma, così tanto tempo per tirare fuori roba che non fosse la classica pezza sfruttando qualche buco trovato da qualche parte, col minimo sforzo possibile…

Le scelte della concorrenza

E’ senz’altro vero che se davanti a sé si avesse a disposizione un foglio bianco e senza (forti) vincoli pregressi su cui “disegnare”, ci sarebbe molto più spazio alla fantasia per tirare fuori progetti più “belli” (nonché efficienti e/o prestazionali).

Un esempio è dato da RISC-V, il quale e sebbene sia inizialmente nato come progetto estivo universitario, s’è poi sviluppato indipendentemente fino alla notevole diffusione e supporto che conosciamo e all’inarrestabile successo di cui sta godendo e che continuerà anche in futuro (principalmente grazie al fatto di non avere licenze da pagare).

Ma RISC-V è un “green project“, come si dice in gergo: nuovo di zecca, senza alcun vincolo a cui dover sottostare (a parte quelli auto-imposti dai suoi architetti), ed è stato molto facile evitare di commettere certi errori perché chi l’ha progettato ha fatto tesoro di quelli commessi dagli altri e della storia passata delle altre architetture.

x86 è, invece, un progetto molto vecchio, con un enorme supporto e libreria software alle spalle e… a cui deve dare conto. Sulla carta, quindi, non potrebbe permettersi nulla del genere: ha pesantissimi vincoli a cui sottostare, pena il possibile fallimento (l’esempio di Itanium AKA IA-64, sempre di Intel, dovrebbe essere ben noto).

Esattamente lo stesso si potrebbe dire di ARM e della sua anch’essa blasonata architettura a 32 bit che, però, ha avuto il coraggio di rimettere mano al progetto e rifondarlo su nuove basi quando ha deciso di tirare fuori una sua estensione a 64 bit, arrivando ad AArch64 AKA ARM64, la quale non è compatibile con la precedente ISA a 32 bit (sebbene abbia molto in comune e portarvi le applicazioni non richieda una totale riscrittura).

S’è presa un grande rischio, senz’altro. Che, comunque, ha dato i suoi frutti aprendole la strada a diversi nuovi mercati, tanto che l’azienda si è ormai focalizzata soltanto su questa nuova architettura (non si sono visti sviluppi per la sua ISA 32 bit, in tutte le salse).

Le evoluzioni a 64 bit di x86

Sfortunatamente AMD non ha avuto la stessa forza d’animo quando ha deciso di dare un erede a 64 bit all’80386, e i suoi ingegneri hanno preferito la facile via di rappezzarla quel tanto che basti per arrivare allo scopo, ritrovandoci, adesso, con x64. Idem con Intel che, purtroppo, continua a fare lo stesso con APX.

Si tratta di scelte dolorose, in quanto questo continuo aggiungere pezze all’architettura non fa che aumentarne la complessità, le difficoltà di realizzazione, i costi implementativi (incluso il testing e il debugging dei circuiti), e le relative ricadute in ambito applicativo.

Da una parte l’ISA si mette al passo con la concorrenza (ma è stato veramente poco con x64), offrendo caratteristiche simili (anche più avanzate) e migliorando le prestazioni, ma dall’altra costringe a trascinarsi dietro tutto questo legacy che, alla fine, la rende meno competitiva (gli altri hanno molto meno da portarsi dietro, in ogni core).

Ciò poteva essere accettabile e aveva un senso quando x86 e x64 rappresentavano IL mercato e dominavano qualunque ambito, dal desktop ai laptop, dalle workstation ai server, e perfino i super computer votati all’HPC. Ma l’era di smartphone e tablet ha dimostrato inoppugnabilmente che la compatibilità a tutti costi con queste due architetture non è strettamente necessaria e, anzi, che a volte è pure un peso, e di recente il cambiamento è arrivato anche in ambito laptop, poi nei server, e ultimo anche nei sistemi HPC, i quali tutti hanno abbracciato architetture diverse.

Aggrapparsi ancora alla compatibilità binaria potrebbe, alla fine, risultare in un abbraccio mortale per Intel (mentre AMD s’è assicurata, almeno per ora, un futuro grazie al mercato delle console. Che, però, storia alla mano, ha visto succedersi diverse architetture), se nessuno sarà più disposto a pagare per la quella che viene chiamata “x86 tax senza averne, in cambio, consistenti benefici (che la concorrenza non dovrebbe offrire).

Continuare ciecamente in questa direzione non farà che relegare sempre più Intel in una nicchia di mercato, ribaltando il ruolo che ha avuto finora. L’azienda, insomma, dovrebbe cominciare a chiedersi quale sarebbe il reale valore aggiunto della sua architettura rispetto alle altre e perché si dovrebbe preferire lei e non gli altri.

A questo punto è bene evidenziare che innovazioni come x64 prima e APX poi costringono, in ogni caso, ad abbandonare almeno la compatibilità binaria. Infatti x64 è soltanto parzialmente compatibile con x86 a livello binario e di sorgenti, per cui una banale ricompilazione delle applicazioni non è stato sempre possibile, ma ha richiesto operazioni di porting / adattamenti.

Mentre formalmente ciò non è vero per APX (anche se, di fatto, è ciò che succederà anche per lei, per quanto già spiegato in un precedenza). Intel stessa nell’annuncio ha sottolineato come basti una semplice ricompilazione per trarne beneficio. Ma è anche vero che ricompilare un progetto per APX porti inevitabilmente a ottenere eseguibili incompatibili per i processori che implementano soltanto le altre architetture x86/x64.

Si sarebbe potuto, quindi, pensare di introdurre una nuova architettura similmente a ciò che ha fatto ARM con AArch64, tagliando definitivamente i ponti con tutto il legacy (o, almeno, per la maggior parte), e offrendo comunque una piattaforma in cui il costo del traghettamento del codice non sarebbe stato elevato (completa riscrittura) o sarebbe stato molto piccolo.

Un recente, ma timidissimo, segnale in tal senso l’ha fornito Intel stessa con X86-S (di cui ho parlato in un recente articolo), la quale non è una nuova architettura, quanto una versione di x64 a cui è stata tolta un bel po’ di roba legacy che effettivamente non viene usata praticamente più da nessuno e che serve soltanto ad appesantire il core e aumentare i consumi (non tutti i transistor inutilizzati si possono spegnere, anche se Intel e AMD hanno fatto un gran lavoro per cercare di ridurne al minimo i consumi).

Si tratta del classico “vorrei, ma non posso”: c’è la consapevolezza di portarsi dietro troppa roba obsoleta che tarpa le ali ai propri prodotti, ma l’azienda non trova mai il coraggio di dare un taglio netto col passato, presentando qualcosa di realmente innovativo e che non sia visceralmente legato al cordone ombelicale del legacy (per quanto di successo esso sia stato).

E poi APX… e altre proposte

Si arriva, dunque, ad APX, che è figlia di questa mentalità / modus operandi ancora troppo pesantemente legata al passato e da cui sembra essere impossibile sfuggire. Sì, le innovazioni ci sono tutte, sono grandiose nonché attese da parecchio tempo, ma la loro struttura & implementazione sono, come già ampiamente discusso, un’altra pezza su un progetto ormai troppo obsoleto (e questo persino utilizzando le migliorie che ho suggerito nel precedente articolo).

Una strategia decisamente più lungimirante sarebbe stata quella di imitare ARM con AArch64 e, quindi, progettare una nuova architettura con le innovazioni desiderate, ma rimuovendo completamente tutto il legacy accumulato finora.

Si sarebbe trattato, allo stesso modo, di un qualcosa a più lungo termine, poiché l’idea è quella di introdurre la nuova ISA supportando allo stesso tempo quella vecchia (x86 e x64, nello specifico), in modo da favorirne la diffusione, e con l’obiettivo finale di dare il benservito alle vecchie architetture una volta raggiunta una certa massa critica riguardo a software e supporto disponibili, similmente a quanto accaduto con x64 (che ormai ha quasi completamente rimpiazzato x86: i s.o. più importanti e diffusi non sono più sviluppati per quest’ultima).

Ovviamente ciò comporterebbe un costo superiore da pagare inizialmente, in quanto implementare una nuova architettura non è la stessa cosa rispetto ad aggiungere una pezza, pur complessa come quella necessaria per aggiungere APX a x64. Ovviamente dipende anche da come sia progettata la nuova architettura, perché potrebbe anche essere abbastanza semplice da richiedere un costo contenuto rispetto alla pezza di APX.

Un ulteriore vantaggio con quest’approccio sarebbe quello di poter realizzare la stessa cosa per codice a 32 bit, cioè una nuova architettura a 32 bit. Questo perché attualmente l’unica a disposizione nel mondo di Intel (ma ovviamente lo stesso vale per AMD) è la vecchia x86, per la quale è impossibile aggiungere i benefici di APX (per lo meno per come sono stati concepiti) né tanto meno è possibile utilizzare estensioni come AVX-512.

Potrebbe sembrare anacronistico pensare di introdurre una nuova architettura a 32 bit, quando tutto il mondo si sta spostando verso i 64 bit, ma una buona ISA a 32 bit ha i suoi intrinseci vantaggi, rappresentati dal fatto che i puntatori occupano 32 bit, per l’appunto, anziché 64, consentendo di ridurre la dimensione delle strutture dati in memoria e, conseguentemente, la pressione sulla cache dati (e, in generale, sull’intera gerarchia della memoria).

Poi non è nemmeno comune, per un’applicazione, utilizzare più di 4GB di memoria (virtuale), per cui queste si potrebbero compilare sempre a 32 bit in modo da sfruttare i suddetti vantaggi. Si potrebbe obiettare che ormai i videogiochi moderni siano tutti a 64 bit perché richiedono più di 4GB di RAM, ma in realtà la stragrande maggioranza dello spazio è occupato dagli asset (in particolare le texture), per cui è pensabile di continuare a utilizzare 32 bit per tutto ciò che deve processare la sola CPU.

Infine, nulla toglie che un s.o. a 64 bit possa far girare applicazioni a 32 bit assieme a quelle a 64 bit, in maniera del tutto trasparente, come già avviene adesso con x64 e potendo, quindi, sfruttare i vantaggi di entrambe.

Ovviamente le due nuove architetture a 32 e 64 dovrebbero essere progettate in modo da essere estremamente simili e con pochissime differenze, in modo da minimizzare i costi implementativi. Il tutto sempre con l’ottica futura di togliere completamente di mezzo sia x86 sia x64 e, con loro, il notevole costo (diversi milioni di transistor per la sola parte legacy, per ogni singolo core).

Infatti è bene precisare, se non fosse ancora chiaro, che la proposta sarebbe quella di mantenere il supporto a x86 e x64 per la compatibilità con l’intero parco software esistente, e al contempo abilitare le due nuove architetture per i nuovi eseguibili che ne farebbero uso. Per i primi anni le quattro architetture coesisterebbero, ma sul lungo termine le due più vecchie sparirebbero per lasciare il posto esclusivamente a quelle nuove.

Inoltre potrebbero anche essere immediatamente commercializzati processori con le sole nuove architetture in settori (server e HPC, per esempio) dove la compatibilità binaria col software esistente non risulta strettamente necessaria. Questo perché si potrebbe già sfruttare appieno i vantaggi di avere core più piccoli e che consumino di meno, in modo da essere subito molto più competitivi con la concorrenza.

Alla fine?

Siamo, quindi, giunti alla fine. E alla fine rimangono soltanto i sogni di qualcosa realmente nuovo, come peraltro si è già intuito da quanto scritto (e, in particolare, nell’ultima parte). Cosa che è sicuramente possibile (tenendo presenti i requisiti di una possibile evoluzione di x86/x64) e di cui parlerò in una futura serie di articoli.

Come abbiamo visto, grazie ad APX Intel si mette al passo della concorrenza, è vero, ma bisognerà vedere per quanto tempo riuscirà ancora a competere trascinandosi una pesante eredità (che, comunque, ne limita già da adesso i mercati su cui può operare proprio a causa di ciò).

La prossima (mini)serie affronterà, come già anticipato, il più longevo e sempiterno dibattito in tema di architetture degli elaboratori: RISC vs CISC. Con l’ardire di… mettervi la parola fine.

Press ESC to close