Quote:
Originariamente inviato da LMCH
Incidono comunque nell'efficienza del decoder, costringendo a ricorrere a soluzioni circuitali più complesse che hanno conseguenze sulla frequenza massima raggiungibile, latenze, ecc.
|
Certamente, e sappiamo che i decoder x86/x64 sono nettamente più complessi rispetto a quelli dei RISC. Su questo non ci piove.
Quote:
Il mio punto era che avevano sottostimato gli effetti negativi di decisioni progettuali che sulla carta sembravano non essere sufficientemente rilevanti.
|
Purtroppo errori del genere li può fare chiunque. Ad esempio le prime versioni degli ARM potevano indirizzare al massimo 64MB di memoria (26 bit d'indirizzamento), e se pensi che sono usciti nel 1985, direi che è stata una decisione folle. Rimanendo su x86, nessuno dei progettisti dell'8086 poteva pensare a dove sarebbe arrivata quest'architettura, e quali problemi avrebbero creato certe scelte che, però, all'epoca erano assolutamente sensate e molto vantaggiose.
Quote:
Ma a causa della loro presenza il set d'istruzioni presenta molti più casi speciali da gestire ad hoc (tipo dove usare prefissi quando si usano certi registri o certe modalità di indirizzamento, ecc. ecc.), mentre sui RISC le estensioni di solito vengono fatte ad un set d'istruzioni che spesso "nasce" per essere decodificato in modo efficiente e lo stesso vale per le estensioni.
|
Tranne per i RISC che... diventano CISC introducendo ISA con opcode a lunghezza variabile, o che magari fanno uso di prefissi.

Il problema è sempre lo stesso: le esigenze cambiano col tempo, e bisogna mettere delle pezze a quanto già realizzato.
A parte questo, la realtà di x86 (e x64) è che la stragrande maggioranza delle istruzioni si mappa 1:1 con le uop, perché... si tratta di istruzioni semplici. Dunque non serve un decoder enormemente complesso per gestire il caso peggiore, con istruzioni molto lunghe (che sono una rarità) o che fanno uso di tanti prefissi (al più se ne usa uno, e questo avviene o per indirizzare memoria locale del thread, oppure quella del s.o., oppure per mappare le istruzioni SIMD). Difatti già da parecchi anni esiste UN solo decoder complesso per gestire tutti i casi possibili, che è affiancato da 2 o 3 (nei processori degli ultimi anni) decoder molto più semplici (ed efficienti / parchi di energia & transistor) che si smazzano le istruzioni molto più comunemente usate.
Ecco
qui un link a un articolo interessante in merito, di cui riporto alcune parti significative:
"In a typical x86 program,
more than 2/3 of the instructions are simple enough to be represented by a single (non-fused) micro-op. Most of the other 1/3 can be decoded into 4 micro-ops or less, with a (very) few taking more to execute. Recognizing these facts, especially the 2:1 simple-to-complex ratio, the P6 design divides its decoders into the well-known 4-1-1 structure, giving only one decoder full capability:
[...]
By differentiating the decoders and put performance emphasis on the common simple-instruction cases, instruction decode and issue complexity can be minimized, and higher clock rate can be reached. RISC design rule #1: Make the common-case fast."
Mi sembra sia abbastanza eloquente.
Per informazioni più dettagliate sui decoder delle varie micro-architetture, c'è il solito Agner Fog e il suo omnio
manuale.
Quote:
Ma trattandosi di set d'istruzioni molto più regolari e simmetrici (nel senso di pochi casi particolari nello schema di decodifica) il costo della retrocompatibilità è di gran lunga inferiore.
|
Certamente, ma ARM si trascina ARM32, Thumb-2, Thumb-EE, e adesso ARM64, che sono abbastanza diverse (solo le due Thumb sono molto simili), quindi servono decoder ad hoc per ognuna, e questo ha certo costo, soprattutto per Thumb.
Quote:
Infatti per esempio a parità di processo produttivo un core Cortex A53 (64bit armv8) occupa il 40% in meno di un core Cortex A9 (32bit armv7) ed in modalità a 64bit ha le stesse prestazioni in termini di capacità di elaborazione.
L'A53 non ha le ottimizzazioni circuitali dell'A9 ma in modalità a 64bit se la gioca alla pari in termini di potenza i calcolo (suppongo nel senso di quando si elaborano dati in unita da 64bit).
|
Le prestazioni per ARMv8 sono migliori perché sono stati raddoppiati i registri general purpose e quelli di FPU/SIMD, portandoli da 16 a 32 (30, in realtà; mi pare che 2 siano riservati per particolari scopi).
Quote:
Insomma anche con l'aumento di complessità dovuto ai 64bit ed al supporto della modalità a 32bit si sono potuti permettere di togliere roba ed avere qualcosa di più "leggero" in termini di implementazione.
|
La roba "pesante" l'hanno tolta soltanto dall'ISA a 64-bit, ma rimane nelle altre ISA, dove continua ad avere il suo peso.
Ha senso parlare di zavorra eliminata soltanto per processori che implementino esclusivamente ARMv8 come architettura.
Quote:
La decodifica da istruzioni THUMB ad istruzioni ARM è 1:1 quindi il "decoder thumb" è un singolo stadio con espansione "a schema fisso" degli opcode THUMB in opcode ARM "classici" (ed eventualmente bypass della word successiva se contiene un valore costante).
Quando si eseguono istruzioni ARM quello stadio viene semplicemente bypassato.
|
Sì, lo so, ma questo stadio in più incide sulle prestazioni di Thumb.
Quote:
Insomma, il supporto di THUMB non pesa sulla decodifica ed esecuzione delle istruzioni ARM a 32bit e quando viene attivato l'incremento di densità delle istruzioni compensa ampiamente gli svantaggi ... presenti solo in modalità THUMB.
|
Per la densità nulla da dire. Ma Thumb rimane una macchina LOAD/STORE, per cui si porta dietro gli stessi problemi dell'architettura ARM32 di cui ho parlato prima... allungati di uno stadio.
Quote:
Questo perche se si sta usando una cpu a 64bit significa che si dispone di molta ram e bus dati molto ampi,
|
Vada per la RAM, che è in continuo aumento, ma non per la dimensione del bus, che può rimanere la stessa. Anzi, vedere bus dati ampii su architetture mobile è difficile a prescindere, per ovvi motivi (di spazio & layout & consumi).
Quote:
senza contare che usando le istruzioni a 64bit si ha nel caso peggiore circa la stessa densità di codice che si avrebbe usando codice ARM a 32bit senza THUMB.
|
Assolutamente no. Dipende dal codice, ovviamente, ma a naso direi che mediamente il codice dovrebbe essere meno denso. Ricorda che da ARMv8 sono state rimosse istruzioni, sì, pesanti, ma anche molto utili e che incidono non poco sulla densità di codice.
Non ho dati in merito, e mi piacerebbe vederne qualcuno, ma per quello che ho visto delle due ISA la mia esperienza mi porta a dedurre che sia così.
Quote:
Se poi consideri che THUMB è stato introdotto essenzialmente per dare il compo di grazia alla concorrenza che per roba embedded proponeva cpu a 16bit o anche ad 8bit ...
|
E' un problema che hanno avuto anche altre ISA. Anche MIPS, se non ricordo male, ha una sua versione "compatta" con opcode a 16-bit. Forse anche SPARC ha qualcosa di simile, ma in generale è un trend ben noto per i processori RISC.
Checché se ne dica, la densità di codice rimane molto importante a prescindere, perché non impatta soltanto sullo spazio occupato, ma anche sulla banda di memoria e sulle cache TLB.
Ecco perché tanti produttori di RISC alla fine sono stati costretti a calare le corna, e adottare un'ISA a lunghezza variabile (e, dunque, CISC; questo era uno dei punti fermi e distintivi fra le due macro-famiglie).
Quote:
Poi sarebbe il caso di ricordare che il vantaggio di compattezza del codice "asimmetrico ed irregolare" degli x86 non è stato decisivo nei confronto degli altri RISC ... ma nei confronti degli Itanium.
|
Ma anche no: Itanium è stata una vittima illustre, in quanto si tratta di un'architettura "di famiglia", ma x86 aveva già fatto fuori tanti altri RISC.