Torna indietro   Hardware Upgrade Forum > Hardware Upgrade > News

ASUS ROG Swift OLED PG49WCD: quando QD-OLED e ultrawide si fondono
ASUS ROG Swift OLED PG49WCD: quando QD-OLED e ultrawide si fondono
Da ASUS un monitor particolare ma molto completo: principalmente indirizzato al videogiocatore, può essere sfruttato con efficacia anche per attività creative e di produzione multimediale
Dreame L10s Pro Ultra Heat: la pulizia di casa tutta sostanza
Dreame L10s Pro Ultra Heat: la pulizia di casa tutta sostanza
Il nuovo robot aspirapolvere domestico di Dreame abbina funzionalità complete a un moccio flottante che raggiunge al meglio gli angoli delle pareti. Un prodotto tutto in uno semplice da utilizzare ma molto efficace, in grado di rispondere al meglio alle necessità di pulizia della casa
HONOR Magic6 Pro: come funziona Magic Portal, il modo ''intelligente'' di condividere
HONOR Magic6 Pro: come funziona Magic Portal, il modo ''intelligente'' di condividere
HONOR ha introdotto con Magic6 Pro la funzione Magic Portal che consente, tramite intelligenza artificiale, di suggerire scorciatoie agli utenti in modo da permettere di passare e accedere facilmente ai servizi tra app e dispositivi con un semplice tocco. Vi spieghiamo qui come funziona
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 06-12-2020, 13:00   #41
386DX40
Senior Member
 
Iscritto dal: Aug 2019
Messaggi: 2690
Quote:
Originariamente inviato da pabloski Guarda i messaggi
15W. Ed è questo il bello. Si tratta del SoC col miglior rapporto mips/watt.



Personalmente preferisco i numeri delle prestazioni rilevate nell'uso con programmi reali. I bench sintetici non sono in grado di offrire una misura onnicomprensiva. Cioè, un Chrome che ti spara le pagine a manetta, renderizza come un matto, esegue codice JS alla velocità della luce, è molto più utile di un bench sintetico.
15W e' quindi il massimo consumo? Sono stati fatti bench sintetici e non, per confrontarlo con qualche processore x64?
386DX40 è offline   Rispondi citando il messaggio o parte di esso
Old 06-12-2020, 13:28   #42
pabloski
Senior Member
 
Iscritto dal: Jan 2008
Messaggi: 8406
Quote:
Originariamente inviato da 386DX40 Guarda i messaggi
15W e' quindi il massimo consumo? Sono stati fatti bench sintetici e non, per confrontarlo con qualche processore x64?
15W è il TDP. Del resto da quando il TDP è il consumo massimo? Proprio Intel ha avviato la pratica di fregarci col TDP.

Considera però che il M1 va negli Air, per cui se non sarà 15W, sicuramente più di 20-25W non supera.
pabloski è offline   Rispondi citando il messaggio o parte di esso
Old 06-12-2020, 15:12   #43
AlexSwitch
Senior Member
 
L'Avatar di AlexSwitch
 
Iscritto dal: Aug 2008
Città: Firenze
Messaggi: 10217
Quote:
Originariamente inviato da pabloski Guarda i messaggi
15W è il TDP. Del resto da quando il TDP è il consumo massimo? Proprio Intel ha avviato la pratica di fregarci col TDP.

Considera però che il M1 va negli Air, per cui se non sarà 15W, sicuramente più di 20-25W non supera.
I 15W di consumo massimo si riferiscono solamente alla CPU ( 13,8W per i core performance e 1.3W per i core a basso consumo ).
In totale il consumo del SoC M1, nella versione più veloce usata nel Mac Mini e secondo le prove empiriche di Anandtech, raggiunge un picco di potenza attiva di 26.8W in multithread su tutti gli 8 core.
La GPU ha raggiunto una potenza di 17.3W.

In un utilizzo reale, dove GPU e/o acceleratori intervengono al posto della CPU o ne sgravano di parecchio il carico di calcolo, M1 non dovrebbe superare i 38W di picco.

I dati della potenza assorbita sono stati rilevati direttamente da Anandtech " alla presa " di corrente, con un idle di 4.2W.
__________________
Mac Mini M2 Pro; Apple Studio Display; Logitech MX Keys for Mac; iPod Touch 1st Gen. 8 Gb; iPhone 14 Pro; iPad Air 2020 WiFi 64 Gb, Apple Watch 8...
AlexSwitch è offline   Rispondi citando il messaggio o parte di esso
Old 13-12-2020, 09:17   #44
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26107
Quote:
Originariamente inviato da Cfranco Guarda i messaggi
Guarda che ormai da 20 anni in qua i processori e l'ISA sono praticamente separati
Diciamo micro-architettura e ISA per fare chiarezza, ma no: non sono affatto separati. Vedi sotto.
Quote:
Non dico che puoi prendere qualsiasi processore, sostituirgli il decoder istruzioni con un' altra ISA e farlo andare uguale, ma non manca tanto ( oddio, nel caso di Transmeta l' ISA in teoria si poteva programmare al volo )
Infatti l'ISA di Transmeta aveva diversi elementi dell'ISA x86 (paginazione della memoria et similia in primis, se non ricordo male), altrimenti avrebbe avuto prestazioni ancora più scarsa.

In generale non puoi avere una micro-architettura completamente slegata dall'ISA. Se t'interessano le prestazioni, ovviamente.
Quote:
E oltretutto le prestazioni migliori le ottieni con le estensioni dedicate, che son tutta roba nuova.
Sì, fanno certamente la parte del leone, ma si può fare molto anche a livello di ISA general-purpose.

Infatti ci sono benchmark in cui le scelte troppo semplicistiche di RISC-V hanno mostrato il fianco.
Un esempio è la presenza di una sola modalità d'indirizzamento verso la memoria (Registro base + piccolo offset), che pone non pochi problemi da questo punto di vista.
Problemi che a cui hanno cercato in parte di rimediare introducendo il merging di due istruzioni compatte, e dunque richiedendo sia l'estensione C/Compatta sia la modifica del frontend del processore per intercettare questi pattern e generare un'apposita istruzione interna che fa il lavoro (e quindi una modifica anche del backend).
Questo succede quando si fanno scelte miopi, andando a cercare la "purezza" a livello accademico, e dimenticandosi di come vadano le cose nel mondo reale...
Quote:
Originariamente inviato da Sp3cialFx Guarda i messaggi
Facciamo finta che siamo nel 2020 e non nel 1990.
Parlare di "ISA x86" come se fosse un vincolo non ha senso perché ormai è 25 anni che le cpu x86 usano il microcode; in altre parole l'ISA x86 non ha corrispondenza nel silicio. Gli x86 sono core RISC con una piccolissima fetta di silicio dedicata alla traduzione tra ISA x86 al microcode.
Non è affatto così: sia il backend sia il frontend dei processori x86/x64 sono (ovviamente) strettamente legati a queste ISA.

Il fatto che internamente ci sia un backend RISC è soltanto un dettaglio implementativo, e in ogni caso tale backend è legato all'ISA, per l'appunto. E non potrebbe essere altrimenti, se l'obiettivo è di avere prestazioni elevate.
Quote:
Ora, se l'M1 di turno EMULANDO VIA SW un x86 gira al 80/85% del nativo, darei per scontato che il traduttore hardware ISA x86 -> microcode che è integrato nelle CPU x86 possa andare anche oltre.
Stai confrontando due cose completamente diverse.

Rosetta emula soltanto lo user-mode di x86/x64, e nemmeno tutto (e no: non mi riferisco soltanto alle istruzioni mancanti. Vedi sotto).

Un processore x86/x64 deve implementare & eseguire invece TUTTO: dall'hypervisor fino agli "anelli di protezione" (ring mode), passando per la segmentazione e la paginazione.

Se Rosetta dovesse emulare TUTTO ciò che è specificato nell'ISA x86/x64 andrebbe a manovella. Provate a realizzare un emulatore x86/x64 pienamente compatibile con tutte le specifiche dell'ISA, e lo vedrete voi stessi come andranno poi le prestazioni, anche girando sui futuri M10 di Apple...

Comunque non è quello lo scopo di Rosetta, e per quello che fa va benissimo così.
Quote:
Fatta tutta questa lunga premessa la mia domanda è:
con le risorse / esperienza di Intel e AMD, e con la possibilità che hanno gli x86 di avere sotto il cofano qualsiasi tipo di core piaccia loro, com'è che Apple tira fuori M1, questi tirano fuori un RISC-V, domani arriva Qualcomm con gli 865 e rimangono al palo?
La mia risposta la trovi proprio qui sopra.
Quote:
Disclaimer: gradirei risposte TECNICHE per capire qual è il tassello che mi manca, di chiacchiera da bar ne ho già letta a sufficienza quindi i pipponi su innovazione / ISA x86 / memoria unificata e bla bla anche no grazie
Spero che la mia breve risposta sia stata sufficiente ad appagare la tua curiosità.
Quote:
Originariamente inviato da pabloski Guarda i messaggi
E c'è la questione di quanta incide il legacy. Cioè tu hai transistor che sono presenti solo perchè ci sono funzionalità legacy da mantenere. Questi transistor sono attivi, consumano corrente. Ciò può limitare la quantità di corrente che puoi dare ad altre subunità ( i processori sono oggetti fisici, attraversati da quantità di elettricità notevoli, che vanno dissipate...e la gestione dell'energia implementata nei moderni processori fa i salti mortali, aumentando/diminuendo tensioni e frequenze dinamicamente nelle varie zone del chip ) e quindi le relative prestazioni.
[...]
In soldoni, meglio bagaglio legacy ti dà (1) più libertà nella progettazione delle unità funzionali ( e se sei bravo le rendi più efficienti ), (2) meno zavorra elettronica da portarsi dietro solo per mantenere cose come la segmentazione ( che non è usata manco per sbaglio in modalità long, cioè quella x86_64 ).
Il legacy non incide molto. Ho postato un link giusto poco fa in un altro thread.

Quando lavoravo alla Intel ho avuto la possibilità di visionare dei webinar interni che analizzavano proprio queste cose, e la percentuale sia di silicio sia di consumi relativi strettamente al legacy erano basse. Non posso dire altro perché è tutta roba riservata.

Comunque ci si può arrivare lo stesso induttivamente. I complessi decoder x86/x64 sono cresciuti relativamente poco dai tempi del PentiumPro, e idem la parte legacy del backend (vecchie istruzioni, FPU x87, segmentazione, registri controllo/debug/machine, ecc.). Oggi abbiamo chip con decine di miliardi transistor: quanto pensi che possa incidere ancora quella roba sia in termini di transistor/silicio sia in termini di consumi?

Queste valutazioni le avevo già fatte in un mio vecchio articolo su Appunti Digitali, che rimane ancora attualissimo. In sintesi: più è piccolo un core x86/x64, e più incide il legacy. E' qui, in questo contesto, che i processori basati su questa vecchia ISA perdono.
Quote:
Originariamente inviato da LMCH Guarda i messaggi
Il motivo per cui i core Apple sono così è che il rapporto costo/benefici è a favore di decoder più ampi perchè si riesce ad estrarre un maggior numero di istruzioni senza troppe interdipendenze rispetto allo stesso codice compilato per x86-64 (i 16 registri interi in più e le istruzioni più semplici da decodificare velocemente aiutano parecchio) e questo poi ha conseguenze anche sul numero di buffer di riordino ed altre cose a valle del decoder.
L'M1 ha oggettivamente di gran lunga più risorse interne votate al raggiungimento di prestazioni elevate, a prescindere dal confronto con l'ISA x86/x64. Lo si può vedere anche confrontandolo con altri processori ARM di altre aziende (Qualcomm in primis): non c'è storia.

Quanto a x86/x64, essendo CISC ha, invece, minori interdipendenze rispetto ai RISC, visto che consente alla maggior parte delle istruzioni di operare direttamente con la memoria.
Anche per questo richiede meno registri, e tempo fa ho postato uno studio in cui un x64 con 12 registri aveva quasi le stesse prestazioni della versione normale con 16 registri (a fronte di una maggior pressione verso la memoria, ovviamente, ma non era nemmeno tanto).
Infine x86/x64 ha diverse modalità d'indirizzamento verso la memoria, e anche queste aiutano.
Certamente avere istruzioni a lunghezza variabile, ma soprattutto facenti uso dei famigerati prefissi (è questo il vero problema), richiede decoder di gran lunga più complessi rispetto a ARM, specialmente se il processore implementa esclusivamente l'ISA AArch64. Ecco perché Apple riesce a decodificare ben 8 istruzioni per ciclo di clock contro 4 (non 5. Nel diagramma di Skylake sono riportate 5uop: non 5 istruzioni) di Intel/AMD.
Quote:
Originariamente inviato da TheAlchemyst Guarda i messaggi
Scusate la domanda da non programmatore, ma se si ha una architettura diversa (x86, arm, questa nuova), il problema per avere dei programmi che vi girano non sta soprattutto nel supporto da parte del compilatore? Cioè, se io ho il sorgente di un programma, il porting su un architettura diversa non dipende solamente dal fatto che uso un compilatore che sa tradurre in linguaggio macchina specifico per quell'architettura? Ovviamente se il programma necessità di set di istruzioni che non sono presenti in quella specifica CPU il discorso cambia, bisogno modificare il sorgente. O sbaglio?
Visto che nessuno t'ha risposto, lo faccio io: non sbagli. E' proprio come hai detto.
Quote:
Originariamente inviato da pabloski Guarda i messaggi
E poi c'è tutto il discorso sulla parte hardware, che ho fatto sopra, che ti fa capire perchè ha senso usare qualcos'altro ( magari realizzato ex novo ) rispetto a x86 o anche ARM, che pure ha il suo legacy.
E' vero, e anche ovvio: se parti da zero e hai le mani completamente libere puoi realizzare un'ISA particolarmente efficiente.

Ma anche avendo dei vincoli importanti si possono realizzare delle ISA "migliori" / più efficienti. Un esempio è proprio l'8086, che era quasi al 100% compatibile a livello di sorgente con l'8085 (traducendo meccanicamente i sorgenti assembly di quest'ultimo in quelli 8086), ma la nuova ISA era a 16 bit e molto migliorata.
Quote:
Si parlava di RISC-V e di come potrebbe fare le scarpe pure ad ARM. Ed è possibilissimo. E non è semplicemente una questione di microdice, ma di quanti transistor puoi liberare, non dovendo supportare funzionalità legacy.
Il vantaggio di RISC-V, come dicono gli stessi creatori, non è in una qualche sua intrinseca efficienza, ma per il fatto di essere open / senza licenze.

RISC-V si porta anch'essa dei problemi / errori di progettazione, e non da poco.
Quote:
Esempio banale: se ritornassimo indietro, levassimo il microcodice, e progammassimo direttamente nel linguaggio macchina della CPU, avremmo un miglioramento? Si, perchè avremmo meno transistor/li potrebbe usare per implementare ulteriori unità funzionali, utili a scopi pratici.
Se ti riferisci alla programmazione diretta del processore che sta nel backend di x86/x64, allora scordatelo: oltre a essere molto più complicato da programmare, le prestazioni crollerebbero drasticamente.
Quote:
Originariamente inviato da Sp3cialFx Guarda i messaggi
Arriva Apple che ha un botto di know how ma non nelle CPU (ha fatto due acquisizioni di aziende che definirei piccole) e fa l'M1 (*)
Ma assolutamente no. Apple ha parecchia esperienza nello sviluppo di CPU/processori, anche perché s'è portata dietro delle eccellenza in questo campo.

Le due acquisizioni di cui parli saranno state pure piccole, ma estremamente importanti.
PaSemi era costituita da eccellenze, per l'appunto, e aveva sviluppato processori PowerPC a uso embedded / militare con un'elevata efficienza energetica.
Intrinsity (se non ricordo male il nome) era specializzata nell'ottimizzazione di circuiti integrati per migliorare le prestazioni (inclusi i consumi).
Dire un'eccellente combinazione, soprattutto funzionale agli scopi di Apple.
Quote:
Il fatto che l'M1 sia avanti di un nodo nel processo produttivo sicuramente aiuta ma non è sufficiente a chiudere la questione.
Incide molto anche quello.
Quote:
Originariamente inviato da pabloski Guarda i messaggi
Ecco. Questo è uno dei punti da chiarire. M1 e tutti i SoC Apple NON SONO ARM!! Implementano l'ISA ARM, ma i design hardware sono totalmente diversi e molto probabilmente ( e ripeto, si può solo supporre, perchè è roba protetta da segreto industriale ) si tratta di chip Power o Power-like, dato che gli ingegneri della PA Semi lavorano su chip Power.
Assolutamente no: sono ARM. Il fatto che PASemi avesse sviluppato PowerPC non vuol dire proprio nulla.
Quote:
Quello che si sa per certo, è che i SoC Apple hanno delle pipeline estremamente ampie e sono aggressivamente superscalari, cosa strana per il mondo ARM tradizionale.
Anche per x86/x64, se è per questo. Il backend di M1 è a dir poco mostruoso.
Quote:
E potrebbe essere dei design clockless, dato che proprio ARM ci aveva lavorato in passato per tentate di abbattere i consumi elettrici.
No, non era quello il lavoro che faceva Intrinsity.
Quote:
Originariamente inviato da LMCH Guarda i messaggi
Riguardo istruzioni x86-64 ed istruzioni AArch64, la densità del codice ed il numero di microOp generate da una singola istruzione dell'ISA, da soli non sono un buon indicatore delle prestazioni.
Premesso che x86-64 non ha una buona densità di codice e che AArch64, pur a lunghezza fissa, si difende molto bene, invece la densità di codice è molto importante.

A riguardo c'è uno studio proprio di uno dei creatori di RISC-V, che afferma che un processore con codice del 25% più denso può usare una cache istruzioni dimezzata (sì, hai letto bene) ottenendo le stesse prestazioni (della cache). Quindi, come vedi, è MOLTO importante. E non è un caso che praticamente i produttori di processori abbiano cercato di migliorare la densità di codice, proponendo estensioni alle loro ISA, o anche ISA realizzate ad hoc.

Sul numero di micro-op generate, invece, non si può dire niente, perché dipende tutto dall'ISA e dal "lavoro utile" che fanno. E questo difficilmente si può quantizzare (magari si dovrebbe vedere il totale delle micro-op eseguite da una precisa applicazione con un preciso set di dati).
Quote:
Gli x86-64 hanno si istruzioni più "complesse" espandibili in un maggior numero di microOp, ma sono anche sequenze di microOp con interdipendenze che vanno riorganizzate a carico di decoder e scheduler invece che a più alto livello (ed in modo più efficiente) dal compilatore o dal programmatore.

Dall'altro lato, se si usano le istruzioni "semplici" degli x86-64, poi si scopre che servono più istruzioni "semplici" x86-64 per fare quello in cui magari basta una singola istruzione "semplice" di AArch64.
Succede anche (e soprattutto) il contrario, come già detto prima, perché la maggior parte delle istruzioni x86/x64 possono referenziare direttamente la memoria. E questo crea meno dipendenze, rispetto ai RISC che devono ricorrere a Load + Op, con annessa dipendenza fra le due istruzioni (nonché aumento dello spazio richiesto per contenere le due istruzioni).
Quote:
Ed infine c'e' il problema del numero di registri interi, x86-64 ha 16 registri interi a 64bit, quando arrivi ad usarli tutti si finisce con il dove accedere a variabili in memoria esterna, con istruzioni più lunghe e con aumento della pressione sulle unità di load/store.
Sì, ma ne servono anche molto meno per quanto detto prima e proprio qui sopra.
Quote:
Gli x86-64 più recenti hanno un sacco di ottimizzazioni interne per rendere più performante l'uso ripetuto della stessa variabile in memoria senza dover passare manco per la cache (per dirla in modo molto grossolano ed approssimativo, tengono il valore nel buffer di riordino e lo recuperano da li o dalla coda di scrittura verso la memoria se un istruzione successiva legge/scrive la stessa locazione), ma questo comunque forza ad usare istruzioni più lunghe (riducendo la densità del codice e riducendo il numero di altre istruzioni decodificabili nello stesso ciclo).
E' l'esatto contrario, invece: la densità di codice migliora, invece, perché il numero di byte occupati da un'istruzione che referenzia la memoria è sempre ben più ridotto rispetto allo stesso numero di byte richiesti da ALMENO due istruzioni RISC (non solo ARM) che debbano fare la stessa cosa.
Parimenti è ridotto anche il numero di istruzioni da codificare, proprio perché x86/x64 ne decodifica una, mentre un RISC per fare lo stesso ne decodificare ALMENO due.

Qui il vantaggio di un CISC come x86/x64 è nettissimo rispetto ai RISC. Non c'è proprio storia.
Quote:
Invece un ARM Aarch64 o un Risc-V (a 32 o a 64 bit) quando un x86-64 deve cominciare a referenziare la memoria, hanno ancora altri 15 registri interi liberi che il programmatore/compilatore può utilizzare per tenere valori temporanei, puntatori, valori riutilizzabili in istruzioni successive, ecc. ed usando istruzioni "semplici" a tutto vantaggio della semplicità del decoder (quindi più facile da "allargare" per decodificare più istruzioni contemporaneamente) e del parallelismo interno in fase di esecuzione.
Vedi sopra: è un vantaggio dei CISC, invece, perché non gli servono né registri addizionali né devono eseguire più istruzioni per fare la stessa cosa.

Non parliamo poi delle istruzioni in cui il risultato dell'operazione è in memoria, dove il vantaggio diventa ancora più grande, visto che in questo caso i RISC necessitano di Load + Op + Store, mentre x86/x64 fa tutto con UNA sola istruzione.

Infine, e non meno importante, ci sono istruzioni x86/x64 il cui la destinazione è la memoria e la sorgente è un valore immediato. Qui il vantaggio rispetto ai RISC si fa addirittura imbarazzante, visto che x86/x64 non spreca un solo registro e fa tutto con una sola istruzione, mentre un RISC richiede più registri (anche più di 2) e MOLTE più istruzioni (specialmente se l'immediato non è piccolo).

Non è che x86/x64 sia arrivato a prestazioni elevatissime per puro caso, eh! E l'ISA CISC ha aiutato, e parecchio.
Quote:
Ripeto, non è un caso se gli Arm di Apple già a 28nm decodificavano 6 istruzioni per ciclo, mentre gli x86-64 non vanno oltre le 4..6 istruzioni neanche ora che sono implementati a 10nm .. 7nm
(es: lo Zen3 in condizioni ottimali decodifica fino a 4 istruzioni x86-64 "semplici" per ciclo e fino ad 8 microOP per ciclo già predecodificate nella uOp Cache, ma invia in esecuzione allo scheduler solo 6 micro-op per ciclo tra i potenzialmente 12 candidati all'esecuzione, da cui la stima di "4..5 istruzioni x86 per ciclo" in condizioni ottimali).
Sono sempre 4 istruzioni decodificate per Intel e AMD.
Quote:
Notare anche che, al momento solo Apple si è spinta a simili livelli di ampiezza del decoder istruzioni, i core di ARM Ltd. non sono così spinti perchè li si è scelto di privilegiare lo sviluppo delle istruzioni SVE2 in modo da rendere più semplice ai produttori su licenza la possibilità di "regolare il livello di prestazioni" cambiando l'ampiezza delle unità SVE.
Le due cose non sono legate. In futuro Apple continuerà ad avere grande ampiezza dei decoder e molto probabilmente aggiungerà il supporto alle SVE/2.
Quote:
Originariamente inviato da LMCH Guarda i messaggi
Per ora il rischio frammentazione non c'e', le specifiche sono molto chiare e la RISC-V International Association si sta attrezzando per limitare ulteriormente i rischi di frammentazione.
E invece c'è eccome. Quando sono partiti con le estensioni ne avevano fissate alcune perché pensavano che andasse bene così. Poi si sono accorti (troppo tardi: ormai le estensioni erano state ratificate) e hanno iniziato a suddividere tali istruzioni in più sottoinsiemi, generando ancora più confusione.

I soliti accademici idealisti che non tengono conto della realtà...
Quote:
A parte questo, sarei curioso di capire cosa hanno DAVVERO realizzato quelli di Micro Magic.
Non basta dire "Risc-V a 64bit che funziona a 5GHz", perchè c'e' molta roba differente che corrisponde ad una descrizione simile.

Questo perchè "Risc-V" è una famiglia di set di istruzioni, mica solo uno, senza contare tutte le differenti implementazioni architetturali che già esistono.

Ad esempio, se hanno implementato un RV64I (la versione "minima" di un Risc-V a 64bit) con un architettura scalare inorder con pipeline lunghissima non è che sia così impressionante, mentre invece se si parla di un RV64GC superscalare la cosa è decisamente più interessante.
Per arrivare a quelle frequenze probabilmente i core saranno in-order. Nulla di impressionante, quindi.
Quote:
In linea generale i Risc-V sono molto promettenti, hanno le loro particolarità ma sono pensati bene e sopratutto sono estendibili in modo retrocompatibile senza dover fare salti mortali assurdi, ma per ora quelli "già pronti" sono gli RV32IMAC .. RV32IMAFC ... RV32GC da usare nella fascia embedded attualmente dominata dagli ARM Cortex M3/M4.
Ehm... no. Stanno pensando (se non l'hanno già fatto) di cambiare alcune parti dell'ISA in maniera non-retrocompatibile, perché si sono accorti, di nuovo, di aver fatto una stupidaggine. Ovviamente nasconderanno il tutto in un'altra nuova estensione, com'è loro abitudine ormai.
Quote:
Originariamente inviato da pabloski Guarda i messaggi
Faccio pure io una provocazione, anzi una domanda. Secondo te, è più facile la vita di un decoder che si occupa di decodificare le istruzioni di un'ISA a lunghezza fissa o di uno che si occupa di un'ISA le cui istruzioni sono a lunghezza variabile?

E quali impatto può avere tutto ciò sulla fase di fetching e sul caching ?
Te ne faccio un'altra io: quale impatto può avere un'ISA con minor densità di codice su fetching e caching? La risposta in buona parte te l'ho già fornita sopra.
Quote:
I registri sono spazio di memorizzazione. Più registri = più roba che si può tenere vicino al processore = meno accessi in memoria/cache. Non è un caso se un'architettura creata per le prestazioni ( Power ) abbia una marea di registri.
E non è nemmeno un caso che POWER abbia in media prestazioni nettamente inferiori a x86/x64, che di registri ne ha molti meno...
Quote:
Originariamente inviato da digieffe Guarda i messaggi
la cache L0 di 4k mops di Zen3 o l'equivalente del prox intel (11xxx) di 2.25k non servono proprio a contenere le sequenze di microistruzioni già decodificate?
E' esattamente quello.
Quote:
Originariamente inviato da pabloski Guarda i messaggi
Dipende a cosa ti riferisci. Questo termine gira da un decennio con vari significati. Ho dato uno sguardo ai manuali Intel giusto per sicurezza, ma nemmeno viene nominato una cache L0.

Altre fonti ne parlano come di un'ulteriore cache prima della L1, con lo scopo di ridurre i consumi.

Altre ancora usano questo termine per riferirsi al register file. Che però contiene i registri generali e ( in alcune famiglie di CPU ) il program counter e lo status register ( i flag ). Ma non mi risulta che l'instruction register sia contenuto nel file.
Cerca meglio: nella documentazione di Intel questa cache L0 si chiama LSD. Ma NON è quello che pensi.
Quote:
E comunque è una tecnica diffusa pure nel mondo ARM e in altre famiglie di CPU moderne. Non è un'esclusiva x86.
Beh, hanno copiato. E non è mica la prima volta che copiano soluzioni di progetti CISC (vedi anche micro-op e macro-op fusion).
Quote:
Originariamente inviato da pabloski Guarda i messaggi
Personalmente preferisco i numeri delle prestazioni rilevate nell'uso con programmi reali. I bench sintetici non sono in grado di offrire una misura onnicomprensiva. Cioè, un Chrome che ti spara le pagine a manetta, renderizza come un matto, esegue codice JS alla velocità della luce, è molto più utile di un bench sintetico.
Dipende da quello che vuoi testare. I benchmark web fanno uso ANCHE della GPU per accelerare alcune operazioni.

Se vuoi testare/confrontare la sola CPU/ISA/microarchitettura ti devi rivolgere ad altri benchmark.

P.S. Scusate ma ho perso un sacco di tempo a scrivere, e non ho nessuna voglia di leggere e correggere eventuali errori. Spero che sia tutto chiaro.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 13-12-2020, 12:02   #45
386DX40
Senior Member
 
Iscritto dal: Aug 2019
Messaggi: 2690
Quote:
Originariamente inviato da AlexSwitch Guarda i messaggi
I 15W di consumo massimo si riferiscono solamente alla CPU ( 13,8W per i core performance e 1.3W per i core a basso consumo ).
In totale il consumo del SoC M1, nella versione più veloce usata nel Mac Mini e secondo le prove empiriche di Anandtech, raggiunge un picco di potenza attiva di 26.8W in multithread su tutti gli 8 core.
La GPU ha raggiunto una potenza di 17.3W.

In un utilizzo reale, dove GPU e/o acceleratori intervengono al posto della CPU o ne sgravano di parecchio il carico di calcolo, M1 non dovrebbe superare i 38W di picco.

I dati della potenza assorbita sono stati rilevati direttamente da Anandtech " alla presa " di corrente, con un idle di 4.2W.
Ecco dove immaginavo si arrivasse..
386DX40 è offline   Rispondi citando il messaggio o parte di esso
Old 15-12-2020, 00:32   #46
LMCH
Senior Member
 
Iscritto dal: Jan 2007
Messaggi: 5264
Quote:
Originariamente inviato da cdimauro Guarda i messaggi
L'M1 ha oggettivamente di gran lunga più risorse interne votate al raggiungimento di prestazioni elevate, a prescindere dal confronto con l'ISA x86/x64. Lo si può vedere anche confrontandolo con altri processori ARM di altre aziende (Qualcomm in primis): non c'è storia.
E può arrivare ad averne così tante perche il set d'istruzioni permette di trarne vantaggio senza dover ricorrere a contorsionisi implementativi come succede con x86-64.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Quanto a x86/x64, essendo CISC ha, invece, minori interdipendenze rispetto ai RISC, visto che consente alla maggior parte delle istruzioni di operare direttamente con la memoria.
Anche per questo richiede meno registri, e tempo fa ho postato uno studio in cui un x64 con 12 registri aveva quasi le stesse prestazioni della versione normale con 16 registri (a fronte di una maggior pressione verso la memoria, ovviamente, ma non era nemmeno tanto).
Infine x86/x64 ha diverse modalità d'indirizzamento verso la memoria, e anche queste aiutano.
Quando sento cose tipo "con 12 registri aveva quasi le stesse prestazioni" di solito lo interpreto come "ma averne 16 permette di avere prestazioni più elevate già ora e maggiori margini in futuro".

Allo stesso modo averne 32 è stato considerato uno sweet spot già con le tecnologie di implementazione e compilazione disponibili negli anni '90 (più di 20 anni fa), non è un caso se sia Alpha che MIPS e PowerPC siano partiti da subito con 32 registri interi e che poi anche ARM con Aarch64 abbia scelto di avere 32 registri interi a 64bit.

Se ARM a più di un decennio di distanza ha privilegiato i 32 registri rispetto ad avere da 1 a 3bit extra da usare ad esempio per ulteriori modalità di indirizzamento ed operandi letti/scritti dalla memoria mi sa che qualche motivo serio ci sia stato.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Certamente avere istruzioni a lunghezza variabile, ma soprattutto facenti uso dei famigerati prefissi (è questo il vero problema), richiede decoder di gran lunga più complessi rispetto a ARM, specialmente se il processore implementa esclusivamente l'ISA AArch64. Ecco perché Apple riesce a decodificare ben 8 istruzioni per ciclo di clock contro 4 (non 5. Nel diagramma di Skylake sono riportate 5uop: non 5 istruzioni) di Intel/AMD.
Forse ti confondi con le architetture precedenti, se non sbaglio una delle caratteristiche di Skylake è che il decoder istruzioni x86/x86-64 può decodificare simultaneamente fino a 5 istruzioni x86 "fresche" (di cui 4 "semplici" che si traducono in una singola uOP ed 1 complessa che viene scomposta in più uOP emesse in sequenza). INOLTRE se le istruzioni x86 sono già presenti in forma decodificata nell uOP cache, possono essere inviate in esecuzione fino a 6 uOP.


Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Premesso che x86-64 non ha una buona densità di codice e che AArch64, pur a lunghezza fissa, si difende molto bene, invece la densità di codice è molto importante.
A riguardo c'è uno studio proprio di uno dei creatori di RISC-V, che afferma che un processore con codice del 25% più denso può usare una cache istruzioni dimezzata (sì, hai letto bene) ottenendo le stesse prestazioni (della cache). Quindi, come vedi, è MOLTO importante. E non è un caso che praticamente i produttori di processori abbiano cercato di migliorare la densità di codice, proponendo estensioni alle loro ISA, o anche ISA realizzate ad hoc.
Se l'aumento della densità del codice penalizza troppo l'espressività, il guadagno che si ha a livello di dimensione della cache istruzioni viene vanificato.
Inoltre non è una cosa "vera in assoluto", dipende molto dalle latenze negli accessi a registri, cache e memoria e dalla banda di I/O, nel senso che sono cose da valutare caso per caso e con il cambiare delle opzioni implementative.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Succede anche (e soprattutto) il contrario, come già detto prima, perché la maggior parte delle istruzioni x86/x64 possono referenziare direttamente la memoria. E questo crea meno dipendenze, rispetto ai RISC che devono ricorrere a Load + Op, con annessa dipendenza fra le due istruzioni (nonché aumento dello spazio richiesto per contenere le due istruzioni).
D'altro canto, a differenza che negli x86-64, in un risc con un sufficiente numero di registri, il compilatore o il programmatore possono schedulare la load in anticipo ed hanno maggiori possibilità di riuscire ad inserire altre istruzioni da eseguire rima di arrivare all'eseguire l'operazione sul dato.
E' un vantaggio non da poco visto che agli x86 sono state aggiunte istruzioni di prefetch proprio per poter fare la stessa cosa (annullando il "vantaggio" teorico che hanno referenziando direttamente la memoria ... per avere un vantaggio concreto).

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Sì, ma ne servono anche molto meno per quanto detto prima e proprio qui sopra.
Skylake: 1 istruzione complessa e 4 semplici oppure ... giù di prestazioni fino al worst case di una istruzione complessa in parziale decodifica.
M1: 8 istruzioni e giù fino a ... diciamo almeno 4 istruzioni se si usa un compilatore con attivati loop unrolling ed auto-inlining.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
E' l'esatto contrario, invece: la densità di codice migliora, invece, perché il numero di byte occupati da un'istruzione che referenzia la memoria è sempre ben più ridotto rispetto allo stesso numero di byte richiesti da ALMENO due istruzioni RISC (non solo ARM) che debbano fare la stessa cosa.
Parimenti è ridotto anche il numero di istruzioni da codificare, proprio perché x86/x64 ne decodifica una, mentre un RISC per fare lo stesso ne decodificare ALMENO due.

Qui il vantaggio di un CISC come x86/x64 è nettissimo rispetto ai RISC. Non c'è proprio storia.
Ma quanto è frequente questo caso ideale per i CISC ? E quanta pressione viene fatta sulle unità di load-store ? Perchè poi se vai a saturare la capacità delle unità di load/store vanifichi tutti i potenziali vantaggi.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Vedi sopra: è un vantaggio dei CISC, invece, perché non gli servono né registri addizionali né devono eseguire più istruzioni per fare la stessa cosa.
Con un aggravio sulla complessità del decoder di istruzioni, della rappresentazione delle uOP e della circuiteria di scheduling e ritiro delle uOP.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Non parliamo poi delle istruzioni in cui il risultato dell'operazione è in memoria, dove il vantaggio diventa ancora più grande, visto che in questo caso i RISC necessitano di Load + Op + Store, mentre x86/x64 fa tutto con UNA sola istruzione.
Correzione, su un x86-64 codifichi il tutto in un unica istruzione che se non sbaglio viene scomposta in 3 uOP il cui scheduling non è detto sia ottimale.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Infine, e non meno importante, ci sono istruzioni x86/x64 il cui la destinazione è la memoria e la sorgente è un valore immediato. Qui il vantaggio rispetto ai RISC si fa addirittura imbarazzante, visto che x86/x64 non spreca un solo registro e fa tutto con una sola istruzione, mentre un RISC richiede più registri (anche più di 2) e MOLTE più istruzioni (specialmente se l'immediato non è piccolo).
Una sola istruzione x86-64 ... che viene espansa in una sequenza di uOP non necessariamente ottimali che aumentano la pressione sulle unità load-store.
Mentre con un RISC con il doppio dei registri, in una sequenza "calda" tipo un loop poni meno pressione sulle unità load/store e vai via molto più veloce.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Non è che x86/x64 sia arrivato a prestazioni elevatissime per puro caso, eh! E l'ISA CISC ha aiutato, e parecchio.
La cosa che più ha aiutato gli x86-64 è stato l'Itanium, di fatto eliminando Alpha e MIPS tramite accordi commerciali riguardo l'adozione di Itanium
si è aperta per AMD la finestra di opportunità in cui proporre con successo x86-64.
Ed una delle innovazione fondamentali di x86-64 è stata estendere il numero di registri interi, non lo dimenticare, altrimenti sai che bello avere le istruzioni CISC con uno dei due operandi in memoria.
E poi diciamolo, x86-64 è arrivato dove è arrivato anche perchè Intel ha spinto l'acceleratore sui processi produttivi, infatti ora che Apple ha fatto la stessa cosa ne è con l'M1 che può permettersi cache più grandi ed un parallelismo interno maggiore grazie al processo produttivo più avanzato (ed al set d'istruzioni Aarch64 che permette di avere un miglior rapporto costi/benefici dall'avere un maggior numero di unità di esecuzione e di buffer di riordino).

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Le due cose non sono legate. In futuro Apple continuerà ad avere grande ampiezza dei decoder e molto probabilmente aggiungerà il supporto alle SVE/2.
Molto probabile, ma già ora con "solo" le estensioni Neon si difende bene, figurarsi dopo.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
E invece c'è eccome. Quando sono partiti con le estensioni ne avevano fissate alcune perché pensavano che andasse bene così. Poi si sono accorti (troppo tardi: ormai le estensioni erano state ratificate) e hanno iniziato a suddividere tali istruzioni in più sottoinsiemi, generando ancora più confusione.

I soliti accademici idealisti che non tengono conto della realtà...
Non capisco, al momento Risc V è una famiglia di set di istruzioni progettata per essere relativamente semplice, efficiente da implementare e libera da IP e brevetti difendibili che creino problemi di implementazione.

E' ancora in evoluzione ed ha ancora un sacco di margini di crescita, inoltre come i due set "base" RV32 e RV64 sono simili ma non compatibili tra loro, nulla vieta di introdurre una nuova sottofamiglia se necessario.
L'unica cosa che creerebbe veri problemi sarebbero breaking changes agli attuali set d'istruzioni "base" (RV32I, RV32E, RV64I e RV128I, di cui RV32E e RV128I non sono stati ancora definiti)

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Ehm... no. Stanno pensando (se non l'hanno già fatto) di cambiare alcune parti dell'ISA in maniera non-retrocompatibile, perché si sono accorti, di nuovo, di aver fatto una stupidaggine. Ovviamente nasconderanno il tutto in un'altra nuova estensione, com'è loro abitudine ormai.
Ma tali modifiche vanno a toccare i set d'istruzione base ? Perchè è un vero problema di retrocompatibilità solo che si ha perdita di retrocompatibilità li.
LMCH è offline   Rispondi citando il messaggio o parte di esso
Old 18-12-2020, 23:25   #47
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26107
Quote:
Originariamente inviato da LMCH Guarda i messaggi
E può arrivare ad averne così tante perche il set d'istruzioni permette di trarne vantaggio senza dover ricorrere a contorsionisi implementativi come succede con x86-64.
Direi proprio di, e sulla "x86 tax" ho già parlato in un altro thread in cui si sono confrontati diversi processori.

M1 ha oggettivamente una montagna di risorse, a prescindere da qualunque altro chip con cui venga confrontato, inclusi quelli di casa ARM.
Quote:
Quando sento cose tipo "con 12 registri aveva quasi le stesse prestazioni" di solito lo interpreto come "ma averne 16 permette di avere prestazioni più elevate già ora e maggiori margini in futuro".
C'è poco da interpretare: basta semplicemente leggere lo studio e i dati, che ho riportato in un altro (ancora) thread.

Poi ti posso dire che personalmente se ci fossero anche più di 16 registri farebbero comodo in alcuni ambiti, ma oggettivamente un CISC (come x86 e, soprattutto, 68K) in genere ne necessita molti di meno per avere comunque buone prestazioni, paragonato a un RISC, per le motivazioni che ho già esposto.
Quote:
Allo stesso modo averne 32 è stato considerato uno sweet spot già con le tecnologie di implementazione e compilazione disponibili negli anni '90 (più di 20 anni fa), non è un caso se sia Alpha che MIPS e PowerPC siano partiti da subito con 32 registri interi e che poi anche ARM con Aarch64 abbia scelto di avere 32 registri interi a 64bit.
Non è nemmeno un caso che siano tutti RISC, che per loro natura hanno oggettivamente bisogno di più registri per fare le stesse cose.
Quote:
Se ARM a più di un decennio di distanza ha privilegiato i 32 registri rispetto ad avere da 1 a 3bit extra da usare ad esempio per ulteriori modalità di indirizzamento ed operandi letti/scritti dalla memoria mi sa che qualche motivo serio ci sia stato.
Son due cose completamente separate / diverse.

Per le modalità d'indirizzamento parliamo esclusivamente di istruzioni di load / store, e non dell'intero insieme di istruzioni. Per questo tipo di istruzioni nessuno t'impedisce di mettere a disposizione più modalità d'indirizzamento, pur preservando tutto il resto dell'ISA, inclusi l'utilizzo di 32 registri.

Difatti uno dei grossi vantaggi di ARM rispetto a tanti altri RISC è stato quello di avere modalità d'indirizzamento molto complicate, persino più complicate di x86 (mi riferisco a quelle di pre-post de/incremento), con innegabili benefici a livello di densità del codice E prestazionali.

Già soltanto per questo ARM vince a mani basse su RISC-V, che una delle ISA più povere e semplici in assoluto, da questo punto di vista (e infatti paga pegno).
Quote:
Forse ti confondi con le architetture precedenti, se non sbaglio una delle caratteristiche di Skylake è che il decoder istruzioni x86/x86-64 può decodificare simultaneamente fino a 5 istruzioni x86 "fresche" (di cui 4 "semplici" che si traducono in una singola uOP ed 1 complessa che viene scomposta in più uOP emesse in sequenza).
Non penso di sbagliare. Ti confondi con le uop che vengono inviate dal decoder alla coda delle istruzioni decodificate, ma le uop non rappresentano il numero di istruzioni decodificate. Il manuale delle ottimizzazioni di Intel non parla mai di quante istruzioni vengano decodificate, ma sempre di uop. Nello specifico: "Legacy Decode Pipeline delivery of 5 uops per cycle to the IDQ compared to 4 uops in previous generations"

Fortunatamente c'è Agner Fog che si passa il tempo a studiare micro-architetture x86/x64, e a fornire i risultati di tali studi. Nello specifico, per Skylake: "There are four decoders, which can handle four instructions (five or six with fusion) generating up to four µops per clock cycle". Quindi più di quattro istruzioni possono essere decodificate soltanto in presenza di macro-op fusion. Normalmente il massimo rimane quattro.
Quote:
INOLTRE se le istruzioni x86 sono già presenti in forma decodificata nell uOP cache, possono essere inviate in esecuzione fino a 6 uOP.
Questo è un altro discorso, che non c'entra coi decoder (era ciò di cui stavamo parlando qui).
Quote:
Se l'aumento della densità del codice penalizza troppo l'espressività, il guadagno che si ha a livello di dimensione della cache istruzioni viene vanificato.
Non so a cosa ti riferisca: potresti chiarire e/o fare degli esempi?
Quote:
Inoltre non è una cosa "vera in assoluto", dipende molto dalle latenze negli accessi a registri, cache e memoria e dalla banda di I/O, nel senso che sono cose da valutare caso per caso e con il cambiare delle opzioni implementative.
No, non è così. Lo studio è stato fatto a parità di tutti gli elementi che hai elencato, e con la sola differenza rappresentata dalla stessa ISA con o senza istruzioni compresse. Quando cambia soltanto una variabile è facile fare confronti, ed è quello che è stato fatto, per l'appunto.
Quote:
D'altro canto, a differenza che negli x86-64, in un risc con un sufficiente numero di registri, il compilatore o il programmatore possono schedulare la load in anticipo ed hanno maggiori possibilità di riuscire ad inserire altre istruzioni da eseguire rima di arrivare all'eseguire l'operazione sul dato.
Questo lo puoi fare anche con gli x86/x64. Peraltro è ancora più facile, visto che non esistono dipendenze coi registri fisici (il dato caricato dalla memoria andrà a finire in uno dei registri interni).
Quote:
E' un vantaggio non da poco visto che agli x86 sono state aggiunte istruzioni di prefetch proprio per poter fare la stessa cosa (annullando il "vantaggio" teorico che hanno referenziando direttamente la memoria ... per avere un vantaggio concreto).
Ma anche no, non ci siamo proprio. Le istruzioni di prefetch servono a tutt'altro, sono presenti anche nei RISC, e non servono a questo, ma ad istruire la logica di prefetch quando ci sono stream di dati a cui dover accedere o manipolare, in modo che le successive (ma molto successive: si parla di decine o anche centinaia di clock "in avanti") si possano trovare quello che gli serve senza o con minime attese.

Le singole istruzioni "general purpose" non fanno uso e non hanno bisogno (in genere) di istruzioni di prefetch. Altrimenti il codice sarebbe letteralmente farcito di queste istruzioni (con notevole crollo prestazionale, visto che la logica di prefetch può "seguire" un numero limitato di stream).
Quote:
Skylake: 1 istruzione complessa e 4 semplici oppure ... giù di prestazioni fino al worst case di una istruzione complessa in parziale decodifica.
M1: 8 istruzioni e giù fino a ... diciamo almeno 4 istruzioni se si usa un compilatore con attivati loop unrolling ed auto-inlining.
OK, e quindi? Ciò non toglie che un CISC come x86/x64 abbia bisogno di meno istruzioni da eseguire rispetto a un RISC, e quindi di meno decoder.

Peraltro se il frontend è organizzato per decodificare un'istruzione complessa e 3 più semplici, è perché si è visto che nel codice reale le istruzioni complesse sono ben più rare di quelle più semplici, e intervallate. Per cui Intel ha organizzato così il frontend.
Quote:
Ma quanto è frequente questo caso ideale per i CISC ?
Direi molto, molto frequente:
https://www.appuntidigitali.it/18192...so-la-memoria/
Guarda pure le tabelle che ho riportato sia per x86 sia per x64, e vedi un po' quante sono le istruzioni che referenziano la memoria.
Poi confrontali con questi numeri: https://www.appuntidigitali.it/18054...di-istruzioni/
Sono state analizzate circa 1,75 milioni di istruzioni (1.746.569 per la precisione) per PS32, e circa 1,74 milioni (1.737.331) per PS64

Quote:
E quanta pressione viene fatta sulle unità di load-store ? Perchè poi se vai a saturare la capacità delle unità di load/store vanifichi tutti i potenziali vantaggi.
La pressione sulle unità di load-store si verifica esclusivamente quando non ci sono abbastanza registri liberi, e quindi si deve salvarne il contenuto nello stack e poi recuperarlo.

Cosa che succede spesso su x86, coi suoi soli 8 registri (nemmeno tutti liberi: uno è lo stack pointer), ma di gran lunga meno con x64 e i suoi 16 registri.
Quote:
Con un aggravio sulla complessità del decoder di istruzioni,
Vero, ma questo attiene soltanto a x86/x64, a causa del modo in cui viene indicata la presenza di un operando verso la memoria, e anche del tipo di operando.

Altri CISC possono fare, e fanno, di gran lunga meglio, con un leggero costo da sostenere per consentire alle istruzioni di referenziare la memoria.
Quote:
della rappresentazione delle uOP e della circuiteria di scheduling e ritiro delle uOP.
Qui, invece, non c'è alcuna differenza coi RISC: una volta trasformate le istruzioni in uOP, il backend le "digerisce" allo stesso modo. Non è un caso che il backend dei moderni processori x86/x64 sia RISC, infatti.
Quote:
Correzione, su un x86-64 codifichi il tutto in un unica istruzione che se non sbaglio viene scomposta in 3 uOP il cui scheduling non è detto sia ottimale.
Sì, vengono divise in 3 uOP, ma lo scheduling rimane ottimale. Non foss'altro perché è il backend a occuparsene, come meglio crede, e certamente e sempre meglio di come farebbe qualunque compilatore. Che poi è anche il motivo per cui le micro-architetture in-order hanno dovuto il cedere il passo a quelle OoO, e perfino ISA (VLIW/EPIC) pensate per essere in-order.
Quote:
Una sola istruzione x86-64 ... che viene espansa in una sequenza di uOP non necessariamente ottimali che aumentano la pressione sulle unità load-store.
Mentre con un RISC con il doppio dei registri, in una sequenza "calda" tipo un loop poni meno pressione sulle unità load/store e vai via molto più veloce.
No, assolutamente: è l'esatto contrario.
Intanto la sequenza di uOP è ottimale (poi se la smazza il backend).
Poi le unità di load/store hanno, invece, pressione minima, perché devono soltanto leggere una volta dalla memoria (il primo operando sorgente; il secondo ce l'hanno già, perché è il valore immediato), e parimenti scrivere (sulla stessa locazione!) una sola volta nella memoria.

Immagina cosa dev'essere costretto a fare un RISC per fare la stessa cosa: o impiega più registri e/o istruzioni già soltanto per costruirsi la costante necessaria, o deve eseguire almeno una load per caricarla dalla memoria. Se ci aggiungiamo anche una modalità d'indirizzamento della memoria più complessa, allora servono altre istruzioni già soltanto per calcolare l'indirizzo desiderato.
Quote:
La cosa che più ha aiutato gli x86-64 è stato l'Itanium, di fatto eliminando Alpha e MIPS tramite accordi commerciali riguardo l'adozione di Itanium
Alpha è morta, ma MIPS è rimasta: non mi sembra che abbia impensierito un granché x86/x64, sebbene sia stata una delle più veloci ISA RISC.
Quote:
si è aperta per AMD la finestra di opportunità in cui proporre con successo x86-64.
AMD non aveva altra scelta, ed è stata fortunata perché Itanium è colato a picco.
Quote:
Ed una delle innovazione fondamentali di x86-64 è stata estendere il numero di registri interi, non lo dimenticare, altrimenti sai che bello avere le istruzioni CISC con uno dei due operandi in memoria.
Sì, i 16 registri general purpose di x64 fanno sicuramente comodo, ma se vedi le statistiche sono ancora parecchie le istruzioni che fanno riferimento alla memoria.
Quote:
E poi diciamolo, x86-64 è arrivato dove è arrivato anche perchè Intel ha spinto l'acceleratore sui processi produttivi,
Che è la stessa cosa che ha sempre fatto IBM coi suoi POWER, e anch'essi RISC ad alte prestazioni.
Quote:
infatti ora che Apple ha fatto la stessa cosa ne è con l'M1 che può permettersi cache più grandi ed un parallelismo interno maggiore grazie al processo produttivo più avanzato
Infatti è in netto vantaggio. E solo lei, visto che s'è accaparrata tutti i wafer a 5nm.
Quote:
(ed al set d'istruzioni Aarch64 che permette di avere un miglior rapporto costi/benefici dall'avere un maggior numero di unità di esecuzione e di buffer di riordino).
Qui non concordo, per quanto già detto: non riguarda l'ISA, ma la micro-architettura di M1 di per sé.
Quote:
Non capisco, al momento Risc V è una famiglia di set di istruzioni progettata per essere relativamente semplice, efficiente da implementare e libera da IP e brevetti difendibili che creino problemi di implementazione.

E' ancora in evoluzione ed ha ancora un sacco di margini di crescita, inoltre come i due set "base" RV32 e RV64 sono simili ma non compatibili tra loro, nulla vieta di introdurre una nuova sottofamiglia se necessario.
L'unica cosa che creerebbe veri problemi sarebbero breaking changes agli attuali set d'istruzioni "base" (RV32I, RV32E, RV64I e RV128I, di cui RV32E e RV128I non sono stati ancora definiti)
Non la segui, mentre io lo faccio da tempo, per cui ho potuto vedere l'evoluzione di questa ISA, delle sue estensioni, delle loro ratifiche / standardizzazioni, e delle ultime "sotto-estensioni" che sono nate per sopperire alle decisioni sbagliate prese con quelle da cui derivano.

Son tutte cose che puoi vedere tu stesso se riesci a recuperare le varie versioni / revisioni del documento delle specifiche dell'ISA.
Quote:
Ma tali modifiche vanno a toccare i set d'istruzione base ? Perchè è un vero problema di retrocompatibilità solo che si ha perdita di retrocompatibilità li.
Le modifiche vanno (o andranno: non so sono state ratificate) a toccare alcune estensioni. In particolare mio riferisco a quella compressa, per la quale si vogliono liberare opcode attualmente allocati per istruzioni FP, in modo da riutilizzarli per altre istruzioni più utili.

Si sono accorti (troppo tardi) che le operazioni di load/store dei registri FP sono molto più rare e incidono meno rispetto ad altre istruzioni.

Per salvare capra (retrocompatibilità) e cavoli (riutilizzo degli opcode) stanno cercando di porvi rimedio con una nuova estensione compressa. Formalmente la retrocompatibilità è salva, perché quei processori non useranno l'estensione compressa standard, ma quella nuova. Di fatto è una presa in giro, perché stanno riutilizzando gli stessi opcode per cose completamente diverse, e quindi si tratta di una modifica non retrocompatibilità. Immagina il lavoro che dovranno fare i disassemblatori per questo giochetto...
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 22-12-2020, 02:50   #48
LMCH
Senior Member
 
Iscritto dal: Jan 2007
Messaggi: 5264
Quote:
Originariamente inviato da cdimauro Guarda i messaggi
C'è poco da interpretare: basta semplicemente leggere lo studio e i dati, che ho riportato in un altro (ancora) thread.

Poi ti posso dire che personalmente se ci fossero anche più di 16 registri farebbero comodo in alcuni ambiti, ma oggettivamente un CISC (come x86 e, soprattutto, 68K) in genere ne necessita molti di meno per avere comunque buone prestazioni, paragonato a un RISC, per le motivazioni che ho già esposto.
Ti riferisci a questa pubblicazione del 2006 ?
https://www.semanticscholar.org/pape...f17059220c2ba4

Nota bene cosa hanno usato per i vari benchmark:
" In this paper, we conducted all the experiments on a Dell Precision Work-
station 370 MiniTower containing a 3.8 GHz Intel Pentium 4 processor."
Un maggior numero di registri "visibili" torna utile al crescere del parallelismo interno, ti credo che con un Pentium 4 passare da 12 a 16 non c'era lo stesso miglioramento che passando da 8 a 12, senza contare che l'ABI prevedeva solo registri caller-saved (mentre di solito quando si hanno molti registri interni le ABI sensate prevedono solo una parte di registri caller-saved ed il resto sono callee-saved proprio per evitare il problema descritto nella pubblicazione).

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Non è nemmeno un caso che siano tutti RISC, che per loro natura hanno oggettivamente bisogno di più registri per fare le stesse cose.
Oppure la cosa può essere vista come, avere più registri visibili costa meno a livello implementativo che avere istruzioni più complesse che poi vanno risc-izzate.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Per le modalità d'indirizzamento parliamo esclusivamente di istruzioni di load / store, e non dell'intero insieme di istruzioni. Per questo tipo di istruzioni nessuno t'impedisce di mettere a disposizione più modalità d'indirizzamento, pur preservando tutto il resto dell'ISA, inclusi l'utilizzo di 32 registri.

Difatti uno dei grossi vantaggi di ARM rispetto a tanti altri RISC è stato quello di avere modalità d'indirizzamento molto complicate, persino più complicate di x86 (mi riferisco a quelle di pre-post de/incremento), con innegabili benefici a livello di densità del codice E prestazionali.
Questo perchè sia i primi ARM a 32bit e che più recenti ARM a 64bit sono stati progettati valutando pro e contro delle possibili opzioni a livello di set d'istruzioni ed implementazione ed anche dei target di mercato.

Così hai i Cortex-M0 (con set d'istruzioni Thumb-2 e varianti successive) che quanto a costo di produzione sono concorrenziali pure con le vecchie cpu ad 8bit, poi i Cortex-M3 e successivi pensati come microcontroller più potenti ma sempre per applicazioni embedded, per salire poi ai Cortex-R (che implementano il set "base" completo di istruzioni ARM a 32bit, hanno varianti dual lockstep, ecc. ) per poi arrivare ai Cortex-A a 32bit e poi a 64bit pensati più per far girare codice applicativo su un S.O. che per roba embedded di fascia bassa).
Guardacaso le cpu con solo Thumb-2 hanno modalità di indirizzamento più "semplici" seppur siano state introdote molti anni dopo le istruzioni ARM a 32bit originali.
Mentre invece le cpu Aarch64 essendo pensate per roba più grossa implementano modalità più complesse (perchè si parte dal presupposto di avere molte più risorse in termini di area e gate per implementare tali cpu).
Con Risc-V invece sono partiti definendo inizialmente il nucleo di istruzioni più semplici e solo ora sta cominciando a venir ratificata la roba più sofisticata.
Non è un caso se la maggior parte delle cpu Risc-V disponibili sul mercato attualmente siano degli RV32IMAC che mirano a scontrarsi al massimo con gli ARM Cortex-M3.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Già soltanto per questo ARM vince a mani basse su RISC-V, che una delle ISA più povere e semplici in assoluto, da questo punto di vista (e infatti paga pegno).
Risc-V è ancora in fase di completamento a livello di estensioni, nulla gli vieta di introdurre un estensione relativa a load/store "con modalità di indirizzamento extra" se proprio risultassero più convenienti.

Ma ho il forte sospetto che per ora non sarà così, per un motivo molto semplice, ovvero che implementa già le modalità di indirizzamento più utilizzate.

Mi riferisco ad esempio a quanto riportato in questa analisi:
http://www.cs.unc.edu/~porter/pubs/i...p-systor19.pdf
Nota che è codice x86-64 e che le modalità di indirizzamento indexed e scaled (che Risc-V non ha) sono usate rispettivamente nel 0.85% e nel 0,44% dei casi ( contro un 7,28% del register-indirect ed un 32,5% del base+offset).

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Non penso di sbagliare. Ti confondi con le uop che vengono inviate dal decoder alla coda delle istruzioni decodificate, ma le uop non rappresentano il numero di istruzioni decodificate. Il manuale delle ottimizzazioni di Intel non parla mai di quante istruzioni vengano decodificate, ma sempre di uop. Nello specifico: "Legacy Decode Pipeline delivery of 5 uops per cycle to the IDQ compared to 4 uops in previous generations"

Fortunatamente c'è Agner Fog che si passa il tempo a studiare micro-architetture x86/x64, e a fornire i risultati di tali studi. Nello specifico, per Skylake: "There are four decoders, which can handle four instructions (five or six with fusion) generating up to four µops per clock cycle". Quindi più di quattro istruzioni possono essere decodificate soltanto in presenza di macro-op fusion. Normalmente il massimo rimane quattro.
Fuochino, il decoder può processare fino a 5 istruzioni x86 per ciclo, ma POI più a valle c'e' il renamer che è limitato ad un output di 4 micro-op per ciclo.
https://www.agner.org/optimize/blog/read.php?i=583

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Questo è un altro discorso, che non c'entra coi decoder (era ciò di cui stavamo parlando qui).
C'entra in termini di istruzioni x86 "pre-decodificate" nella micro-op cache che possono teoricamente essere inviate in esecuzione (se non fosse per il collo di bottiglia del renamer).
Se non sbaglio è il decoder che "comanda" la micro-op cache, in un certo senso è una forma ottimizzata di decodifica.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Non so a cosa ti riferisca: potresti chiarire e/o fare degli esempi?
Guardando sul documento che ho linkato sopra, x86-64 sembra più compatto del codice per ARMv8 ma poi se si analizzano le tipologie di istruzioni si vede che le istruzioni ampie meno di 4 byte sono il 42.4% (di cui il 23.1% ampie 3 byte) , quelle ampie 4 byte sono il 15.9%, quelle da 5 a 7 byte sono il 34.4% e quelle da 8 a 12 byte sono 6.3%.
Mediamente un istruzione x86-64 occupa 4 byte, inoltre lo stesso codice richiede molte più istruzioni move rispetto ad ARMv8, questo significa che i vantaggi legati alle istruzioni più "compatte" degli x86-64 vengono vanificati dalla minor espressività delle istruzioni "più corte" che possono accedere a meno registri e non hanno un move "gratis" come le istruzioni a 3 operandi di ARMv8.
Ovviamente il codice x86 (a 32bit) è più compatto di x86-64, ma seguendo lo stesso ragionamento il codice a 32bit degli ARM lo è ancora di più (istruzioni ARM "classiche" + istruzioni Thumb-2 a 16bit utilizzabili nello stesso codice applicativo).

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Questo lo puoi fare anche con gli x86/x64. Peraltro è ancora più facile, visto che non esistono dipendenze coi registri fisici (il dato caricato dalla memoria andrà a finire in uno dei registri interni).
Lo puoi fare se rinunci al "vantaggio" di usare gli operandi in memoria e caricando i valori da utilizzare su registri interni MOLTO PRIMA di quando poi li utilizzerai (in modo da effettuare il load out-of-order insieme ad altre istruzioni che non dipendono dal valore che stai caricando), solo che questo diventa meno vantaggioso quando si hanno meno registri.
Inoltre lo stesso giochino di caricamento dei valori in memoria lo possono fare anche i RISC facendo molto più semplicemente ed efficientemente il renaming dei registri interni rispetto ad un CISC.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Ma anche no, non ci siamo proprio. Le istruzioni di prefetch servono a tutt'altro, sono presenti anche nei RISC, e non servono a questo, ma ad istruire la logica di prefetch quando ci sono stream di dati a cui dover accedere o manipolare, in modo che le successive (ma molto successive: si parla di decine o anche centinaia di clock "in avanti") si possano trovare quello che gli serve senza o con minime attese.
Le istruzioni di prefetch "esplicito" servono per ottimizzare gli accessi alla cache, mentre le "load con molto anticipo" in architetture load-store fanno semplicemente il prefetch di valori "ottimizzato dal programmatore/compilatore".
Ma resta il fatto che se vuoi ottimizzare l'uso di istruzioni x86-64 con operandi in memoria, a livello di compilatore ti servono le istruzioni di prefetch per limitare i problemi causati dal minor numero di registri visibili al programmatore/compilatore.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Le singole istruzioni "general purpose" non fanno uso e non hanno bisogno (in genere) di istruzioni di prefetch. Altrimenti il codice sarebbe letteralmente farcito di queste istruzioni (con notevole crollo prestazionale, visto che la logica di prefetch può "seguire" un numero limitato di stream).
Mentre questo problema non è così impattante sui RISC per la possibilità di schedulare le load con maggior anticipo tenendo tutto su registri interni.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
OK, e quindi? Ciò non toglie che un CISC come x86/x64 abbia bisogno di meno istruzioni da eseguire rispetto a un RISC, e quindi di meno decoder.
Questo nel caso in cui si riescano a sfruttare le istruzioni più complesse ed i modi di indirizzamento più complessi, mentre a quanto vedo, gli attuali compilatori per x86-64 quando ottimizzano ai settaggi più estremi usano le istruzioni "semplici" che hanno anche i RISC ma con molte più move tra registri.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Peraltro se il frontend è organizzato per decodificare un'istruzione complessa e 3 più semplici, è perché si è visto che nel codice reale le istruzioni complesse sono ben più rare di quelle più semplici, e intervallate. Per cui Intel ha organizzato così il frontend.
E qui si ricade nel caso di CISC in cui si privilegiano le istruzioni Risc, ma con limiti nel numero massimo di istruzioni eseguibili in parallelo.
Altrimenti quelli di ARM avrebbero implementato Aarch64 come un CISC "riscritto da zero e moderno" mentre invece hanno considerata molto più vantaggiosa un architettura "simil-RISC".

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
La pressione sulle unità di load-store si verifica esclusivamente quando non ci sono abbastanza registri liberi, e quindi si deve salvarne il contenuto nello stack e poi recuperarlo.

Cosa che succede spesso su x86, coi suoi soli 8 registri (nemmeno tutti liberi: uno è lo stack pointer), ma di gran lunga meno con x64 e i suoi 16 registri.
Io aggiungerei anche che i compilatori per x86-64 tengono conto delle limitazioni di tale architettura e quindi generano sequenze di codice in cui si hanno meno pre-caricamenti di valori nei registri interni, privilegiano l'uso dei primi 8 registri, ecc. ecc.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Vero, ma questo attiene soltanto a x86/x64, a causa del modo in cui viene indicata la presenza di un operando verso la memoria, e anche del tipo di operando.

Altri CISC possono fare, e fanno, di gran lunga meglio, con un leggero costo da sostenere per consentire alle istruzioni di referenziare la memoria.

Qui, invece, non c'è alcuna differenza coi RISC: una volta trasformate le istruzioni in uOP, il backend le "digerisce" allo stesso modo. Non è un caso che il backend dei moderni processori x86/x64 sia RISC, infatti.
Il problema è che per arrivare al backend Risc serve una "digestione" più lunga e complessa delle istruzioni CISC, cosa che a parità di tecnologia ha il suo peso.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Immagina cosa dev'essere costretto a fare un RISC per fare la stessa cosa: o impiega più registri e/o istruzioni già soltanto per costruirsi la costante necessaria, o deve eseguire almeno una load per caricarla dalla memoria. Se ci aggiungiamo anche una modalità d'indirizzamento della memoria più complessa, allora servono altre istruzioni già soltanto per calcolare l'indirizzo desiderato.
Con la differenza che un Risc HA più registri disponibili per precaricare valori e che i valori immediati nella maggior parte dei casi sono piccoli oppure è vantaggioso caricarli su un registro e utilizzare più volte il registro.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Alpha è morta, ma MIPS è rimasta: non mi sembra che abbia impensierito un granché x86/x64, sebbene sia stata una delle più veloci ISA RISC.
Alpha è morta perchè Compaq ed HP avevano deciso di puntare tutto su Itanium.
A spingere MIPS sui server era SGI, che pure essa è passata ad Itanium e poi ha fatto la fine che ha fatto. MIPS è sopravvissuto nel settore embedded ma ormai è usato principalmente in roba legacy visto che ARM ha confinato MIPS e PowerPC a nicchie ridotte di mercato.
I produttori di cpu/microcontroller embedded per roba nuova a 32bit e 64bit propongono principalmente ARM.
PowerPC resiste come architettura legacy specialmente nell'automotive ma al massimo si vedono degli shrink dei core, niente roba davvero nuova.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Che è la stessa cosa che ha sempre fatto IBM coi suoi POWER, e anch'essi RISC ad alte prestazioni.
Solo che IBM i POWER li propone solo per supercomputer e server di fascia alta, una nicchia molto remunerativa ma nicchia rimane.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Non la segui, mentre io lo faccio da tempo, per cui ho potuto vedere l'evoluzione di questa ISA, delle sue estensioni, delle loro ratifiche / standardizzazioni, e delle ultime "sotto-estensioni" che sono nate per sopperire alle decisioni sbagliate prese con quelle da cui derivano.

Son tutte cose che puoi vedere tu stesso se riesci a recuperare le varie versioni / revisioni del documento delle specifiche dell'ISA.

Le modifiche vanno (o andranno: non so sono state ratificate) a toccare alcune estensioni. In particolare mio riferisco a quella compressa, per la quale si vogliono liberare opcode attualmente allocati per istruzioni FP, in modo da riutilizzarli per altre istruzioni più utili.

Si sono accorti (troppo tardi) che le operazioni di load/store dei registri FP sono molto più rare e incidono meno rispetto ad altre istruzioni.

Per salvare capra (retrocompatibilità) e cavoli (riutilizzo degli opcode) stanno cercando di porvi rimedio con una nuova estensione compressa. Formalmente la retrocompatibilità è salva, perché quei processori non useranno l'estensione compressa standard, ma quella nuova. Di fatto è una presa in giro, perché stanno riutilizzando gli stessi opcode per cose completamente diverse, e quindi si tratta di una modifica non retrocompatibilità. Immagina il lavoro che dovranno fare i disassemblatori per questo giochetto...
Forse ho capito male, ma non mi sembra che sia un vero problema (almeno per ora) visto che al momento il grosso degli utilizzi pratici sono incentrati su core con estensioni IMAC (senza floating point) oppure roba embedded compilata ad hoc, quindi sarebbe una perdita di retrocompatibilità accettabile. In fin dei conti Risc-V non è UN unico set di istruzioni ma una famiglia di set di istruzioni.
LMCH è offline   Rispondi citando il messaggio o parte di esso
Old 22-12-2020, 11:48   #49
amd-novello
Senior Member
 
L'Avatar di amd-novello
 
Iscritto dal: Aug 2001
Città: Novara (NO)
Messaggi: 19637
wall of text versus wall of text

lol
__________________
ASUS N76VZ +crucial m500 Dell Latitude E5430 iPad 2017 Huawei nova 5t con Very samsung tv 55m5500 ps4,wiiu
exVODA 82/18-78/16-77/13-90/11 exWIND 95/14-95/19-85/19-81/22 fritzbox 7490
su Tiscali 936/288
amd-novello è offline   Rispondi citando il messaggio o parte di esso
Old 23-12-2020, 11:23   #50
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26107
@amd-novello Ah, bene. Allora divertiti con quest'altro, visto che ti piacciono tanto.
Quote:
Originariamente inviato da LMCH Guarda i messaggi
Ti riferisci a questa pubblicazione del 2006 ?
https://www.semanticscholar.org/pape...f17059220c2ba4

Nota bene cosa hanno usato per i vari benchmark:
" In this paper, we conducted all the experiments on a Dell Precision Work-
station 370 MiniTower containing a 3.8 GHz Intel Pentium 4 processor."
Un maggior numero di registri "visibili" torna utile al crescere del parallelismo interno, ti credo che con un Pentium 4 passare da 12 a 16 non c'era lo stesso miglioramento che passando da 8 a 12, senza contare che l'ABI prevedeva solo registri caller-saved (mentre di solito quando si hanno molti registri interni le ABI sensate prevedono solo una parte di registri caller-saved ed il resto sono callee-saved proprio per evitare il problema descritto nella pubblicazione).
Scusa, che c'entra il fatto che abbiano usato un P4? E' stato fatto soltanto per estrarre i dati delle ricerche, ma l'ABI usata è quella di x86-64, e non quella di x86, quindi register-based anziché stack-based, anche quando sono stati ridotti i registri a 12.

Ciò che era importante evidenziare è che il passaggio da 12 a 16 registri sostanzialmente non abbia inciso a livello prestazionale.
Quote:
Oppure la cosa può essere vista come, avere più registri visibili costa meno a livello implementativo che avere istruzioni più complesse che poi vanno risc-izzate.
Se le istruzioni complesse "da rischizzare" sono tutte dello stesso tipo (con Mod/RM nel caso di x86/x86-64), il costo è irrisorio: si tratta di emettere uop di load/store oltre a quella di calcolo vero e proprio, e si applica sistematicamente a tutte le istruzioni di questo tipo (basta soltanto sapere che lo siano).
Quote:
Questo perchè sia i primi ARM a 32bit e che più recenti ARM a 64bit sono stati progettati valutando pro e contro delle possibili opzioni a livello di set d'istruzioni ed implementazione ed anche dei target di mercato.
Opinabile. Anche coi primi processori a 32 bit ARM ha commesso degli errori, alcuni madornali: vedi il registro PC a soli 26 bit (quindi max 64MB di memoria indirizzabili), perché gli aveva aggiunto anche i bit del registro di flag/stato. Infatti è stata poi costretta a separarli con la v2 (se non erro), con una modifica all'ISA assolutamente non retro-compatibile. E' stata una visione davvero molto, molto miope.
Quote:
Così hai i Cortex-M0 (con set d'istruzioni Thumb-2 e varianti successive) che quanto a costo di produzione sono concorrenziali pure con le vecchie cpu ad 8bit, poi i Cortex-M3 e successivi pensati come microcontroller più potenti ma sempre per applicazioni embedded, per salire poi ai Cortex-R (che implementano il set "base" completo di istruzioni ARM a 32bit, hanno varianti dual lockstep, ecc. ) per poi arrivare ai Cortex-A a 32bit e poi a 64bit pensati più per far girare codice applicativo su un S.O. che per roba embedded di fascia bassa).
Guardacaso le cpu con solo Thumb-2 hanno modalità di indirizzamento più "semplici" seppur siano state introdote molti anni dopo le istruzioni ARM a 32bit originali.
ARM ha commesso degli errori anche con le estensioni (Thumb-EE e Jazilla che sono sostanzialmente morte, per citarne due abbastanza note).

In particolare Thumb e Thumb-2 sono l'esempio del pastrocchio che ARM ha realizzato quando ha definito la prima, mentre avrebbe potuto semplicemente prendere gli allora opcode ARM, rimuovere i 4 bit per l'esecuzione condizionale, lasciare la sola "condizione" (sempre vera) per l'esecuzione tout-court delle istruzioni, e riutilizzare le altre 15 configurazioni per definire in maniera pulita e semplice le istruzioni compatte a 16-bit. Invece è partita abbozzando malamente la prima, per poi metterci una pezza dopo con la seconda.
Quote:
Mentre invece le cpu Aarch64 essendo pensate per roba più grossa implementano modalità più complesse (perchè si parte dal presupposto di avere molte più risorse in termini di area e gate per implementare tali cpu).
Ma anche qui ARM ha peccato, non avendo definito un'ISA compatta. Vedrai meglio dopo il perché, nel paper dei progettisti di RISC-V che riporterò.
Quote:
Con Risc-V invece sono partiti definendo inizialmente il nucleo di istruzioni più semplici e solo ora sta cominciando a venir ratificata la roba più sofisticata.
Non è così, e ripeto: è perché non hai seguito l'evoluzione di quest'architettura. Infatti diverse estensioni importanti sono già state ratificate, e pure da tempo.

La grossa mancanza riguarda le estensioni vettoriali, perché sono anni che gli accademici sbattono le corna alla ricerca di qualcosa di utilizzabile concretamente nella realtà, e che non li faccia soffrire troppo nello scardinare i loro ideali di "bellezza" dell'ISA che s'erano costruiti (i famigerati soli 3 formati di opcode sono un lontano ricordo, infatti: rimangono un proclama di pura propaganda).
E meno male che a questo comitato si sono uniti diversi ingegneri provenienti da aziende, che hanno i piedi ben piantati per terra, altrimenti sarebbero state ratificate delle colossali stupidaggini, come la definizione dinamica, a runtime, del tipo di dati utilizzato dai registri vettoriali (come da originale proposta, di diversi anni fa), che avrebbe fatto piangere lacrime amare a chi avrebbe dovuto implementarle...
Quote:
Non è un caso se la maggior parte delle cpu Risc-V disponibili sul mercato attualmente siano degli RV32IMAC che mirano a scontrarsi al massimo con gli ARM Cortex-M3.
Ci sono anche altre estensioni già ratificate da tempo. Se non vengono usate è proprio perché al momento le aziende più interessate sono quelle che operano in ambito embedded, a cui bastano quelle istruzioni.

Anzi, quella M e A erano e sono anche di troppo (su quella C mi sono già espresso), ed è proprio il motivo per cui sono poi nate delle loro versioni castrate, aumentando di fatto la frammentazione (visto che M ed A erano già state ratificate, e non si poteva più tornare indietro).
Quote:
Risc-V è ancora in fase di completamento a livello di estensioni, nulla gli vieta di introdurre un estensione relativa a load/store "con modalità di indirizzamento extra" se proprio risultassero più convenienti.
Non lo faranno mai perché per loro l'architettura base è stata definita ed è intoccabile, incluse le istruzioni di load/store. Ti posto già qui il paper di cui ti ho parlato prima, così puoi cominciare a prendere visione di cosa ne pensano e perché sono irremovibili nel difendere le loro scelte: The Renewed Case for the Reduced Instruction Set Computer: Avoiding ISA Bloat with Macro-Op Fusion for RISC-V
Come puoi vedere già il titolo è tutto un programma, e il contenuto non si smentisce.
Quote:
Ma ho il forte sospetto che per ora non sarà così, per un motivo molto semplice, ovvero che implementa già le modalità di indirizzamento più utilizzate.
No. Vedi sopra. Istruzioni di load/store più avanzate sono state proposte da progetti esterni, come il PULP dell'università di Zurigo (l'estensione / progetto più diffuso, e che praticamente è diventato uno standard parallelo), ma rimarranno non standardizzate / ratificate dal comitato RISC-V.
Quote:
Mi riferisco ad esempio a quanto riportato in questa analisi:
http://www.cs.unc.edu/~porter/pubs/i...p-systor19.pdf
Nota che è codice x86-64 e che le modalità di indirizzamento indexed e scaled (che Risc-V non ha) sono usate rispettivamente nel 0.85% e nel 0,44% dei casi ( contro un 7,28% del register-indirect ed un 32,5% del base+offset).
Francamente è una ricerca che lascia il tempo che trova per le modalità utilizzate per estrarre l'elenco delle istruzioni, visto che fanno uso del comando objdump, che per limiti intrinseci disassembla anche blocchi dati, falsando le statistiche.
E' il motivo per cui, ad esempio, trovi un così elevato numero di istruzioni ADD, come puoi vedere anche dal loro sito che consente di consultare il database con le informazioni raccolte. Infatti la ADD è così inflazionata perché si tratta dell'istruzione avente 0x00 come uno dei suoi opcode: dato estremamente comune negli eseguibili, come certamente sai.

Altri paper mostrano risultati abbastanza diversi:
https://www.strchr.com/x86_machine_code_statistics
http://citeseerx.ist.psu.edu/viewdoc...=rep1&type=pdf
http://people.umass.edu/cmutigwe/res...s%20Design.pdf
e soprattutto il paper degli autori di RISC-V che ti ho già passato che, sebbene sia ovviamente (fortemente) "biased", mostra dei dati grezzi che sono molti utili di per sé, oltre al fatto che riporta esclusivamente istruzioni reali, e soprattutto le statistiche sono di quelle dinamiche (quindi tutte e soltanto quelle eseguite realmente in quelle applicazioni) e non statiche (quelle del paper che hai postato).

Tra l'altro anche il bouquet di applicazioni che ho usato per le mie statistiche (anche statiche, sia chiaro) mostra un quadro diverso da quello del tuo paper, e più in linea con gli altri paper. Inoltre non ho disassemblato roba a caso, ma sono partito dall'entry point dell'eseguibile, e ho disassemblato tutto ciò che era possibile, tracciando le istruzioni di salto. Quindi niente spazzatura/dati grezzi disassemblati come istruzioni. Le statistiche le trovi nella mia ultima serie di articoli su Appunti Digitali, dove puoi vedere i dati della beta pubblica di Photoshop CS6, sia a 32 sia a 64-bit.

Ciò precisato, t'invito a leggere il paper che ho postato, e così vedrai che, sebbene la modalità d'indirizzamento indicizzata non sia così diffusa, è molto usata (dinamicamente) in alcune applicazioni ed è il motivo per cui RISC-V ha un crollo a livello prestazionale, di cui gli autori propongo una soluzione (macro-op fusion) per alleviare il problema.

Che il paper sia biased lo si capisce anche dal fatto che si lamentano della scarsa qualità del codice generato per RISC-V (che ci può stare. Anche se loro hanno attivato soltanto per RISC-V un'opzione di GCC per disabilitare la generazione di routine di prologo/epilogo, che altrimenti avrebbero prodotto PIU' istruzioni e micro-op eseguite), ma analizzando il disassemblato x86-x64 in alcuni casi si può vedere come vengano generate istruzioni non necessarie, che ovviamente penalizzano quest'ISA sia a livello prestazionale sia di densità di codice.

Dai pattern che ho rilevato (dagli esempi nel paper) mi sembra evidente che GCC non sia capace di riconoscere quando può evitare di omettere la generazione di istruzioni di confronto quando la precedente istruzione ha già impostato correttamente i flag, che quindi possono essere immediatamente "consultabili" (con un salto condizionale).
E qui parliamo di roba da manuale, eh! Perché per me è OVVIO che l'ottimizzatore del backend x86/x86-64 avrebbe dovuto tenere conto di questi casi molto comuni. Non capisco come sia potuto sfuggire agli sviluppatori di GCC.

Questo per dirti che non è soltanto RISC-V che può lamentare che non sia stato generato codice adeguato, ma persino ISA rodate come x86/x86-64.

Altra cosa non meno importante, i paper in genere fanno soltanto uso di GCC come compilatore, mentre nelle applicazioni reali si usano, e sono pure molto comuni, anche altri compilatori, come quello di Intel e, soprattutto, di Microsoft in Windows.
Questi compilatori ottimizzano molto meglio il codice rispetto a GCC, sia a livello di istruzioni generate sia a livello di densità di codice.
Infatti da ciò che ho visto finora GCC predilige la generazione di codice più "RISC-like", anche quando deve farlo per x86/x86-64. E lo fa a danno soprattutto della densità di codice, che è di gran lunga più scarsa rispetto agli compilatori.

Giusto per rendere l'idea, la lunghezza media delle istruzioni x86 è di 3,42 byte per l'intero bouquet di applicazioni che ho usato (31, delle più svariate: da arm-none-eabi-gdb.exe a WinUAE.exe, passando per ffmpeg_32.exe, Neverwinter.exe, Skype.exe, sublime_text_32.exe, ecc.). Se di queste seleziono soltanto quelle compilate con GCC (sono 6: arm-none-eabi-gdb.exe, cc1.exe, cc1plus.exe, ffmpeg_32.exe, Kodi.exe, lto1.exe), la lunghezza media è di ben 3,93 byte.
Per x86-64, invece, la lunghezza media è di 4,05 byte (su 25 applicazioni), mentre prendendo le sole due applicazioni GCC (soltanto 2: ffmpeg_64.exe, mame64.exe) diventa di ben 5,18 byte (colpa di MAME, che ha lunghezza media molto alta: ben 5,52 byte). Posto che quelle GCC sono troppo poche, il trend rimane comunque superiore a quello delle applicazioni non compilate con GCC.

E ti posso dire che se dovessi tenere conto soltanto di GCC come benchmark da usare per la densità di codice, potrei andare a stappare subito una bottiglia di buon Dom Pérignon, visto che la mia architettura attualmente mostra una lunghezza media nettamente migliore rispetto a GCC (3,25 byte: -17,28% per x86. 3,76 byte: -27,35% su x86-64) che rispetto a tutti i compilatori (incluso GCC. 3,12 byte: -8,72% per x86. 3,26 byte: -19,35% su x86-64).

Questa lunga digressione per chiarire meglio diversi concetti, che poi vengono ripresi anche in altre parti di questa discussione, così si può usare questa parte come comodo punto di riferimento generale.
Quote:
Fuochino, il decoder può processare fino a 5 istruzioni x86 per ciclo, ma POI più a valle c'e' il renamer che è limitato ad un output di 4 micro-op per ciclo.
https://www.agner.org/optimize/blog/read.php?i=583
Sono sempre 4 istruzioni decodificate al massimo (max 5 o 6 col macro-op fusion), ma quello che hai riportato riguarda soltanto il limite dell'attuale implementazione del register renamer, appunto.

C'è qualche altro commento che riporta delle informazioni interessanti. Non riporto tutto il messaggio, ma soltanto la parte iniziale, che è anche la più importante in questo contesto:
Haswell register renaming / unfused limits
Author: Peter Cordes Date: 2017-05-11 09:32
Tacit Murky wrote:
Looks like it's about the number of renamed registers.
Agreed. Simply changing Nathan's loops to use an immediate instead of a register for `max` produces a dramatic speedup on HSW:
Nathan's 2 micro / 2 macro on my HSW: one iteration per 1.42275c (~4.21 unfused-domain uops per clock). Very consistent, +- 0.0001 cycles per iter (for 1G iterations).
cmp r,imm instead of cmp r,max for both compares : one iteration per ~1.12c (~5.35 unfused-domain uops per clock). Pretty noisy, from 1.116c to 1.124c per iter.
Come vedi usare immediati porta dei vantaggi, perché NON si usano registri, e quindi non si applica il limite del register renamer.
Quote:
C'entra in termini di istruzioni x86 "pre-decodificate" nella micro-op cache che possono teoricamente essere inviate in esecuzione (se non fosse per il collo di bottiglia del renamer).
Sì, ma non attiene ai decoder veri e propri, che hanno già fatto il loro lavoro, e in questa parte dell'esecuzione non c'entrano più.
Quote:
Se non sbaglio è il decoder che "comanda" la micro-op cache, in un certo senso è una forma ottimizzata di decodifica.
La decodifica è sempre la stessa, e non è ottimizzata da questo punto di vista. Che ci fosse la micro-op cache o meno, le micro-op devono essere generate per poi essere eseguite dal backend.

Se di ottimizzazioni possiamo parlare è che questa micro-op cache funge sostanzialmente da cache L0, e quindi i decoder non sono sempre attivi. Anzi, mi pare che vengano spenti l'80% del tempo, se non ricordo male le dichiarazioni di Intel di diversi anni fa (probabilmente la situazione è ancora migliorata adesso).
Quote:
Guardando sul documento che ho linkato sopra, x86-64 sembra più compatto del codice per ARMv8 ma poi se si analizzano le tipologie di istruzioni si vede che le istruzioni ampie meno di 4 byte sono il 42.4% (di cui il 23.1% ampie 3 byte) , quelle ampie 4 byte sono il 15.9%, quelle da 5 a 7 byte sono il 34.4% e quelle da 8 a 12 byte sono 6.3%.
Mediamente un istruzione x86-64 occupa 4 byte, inoltre lo stesso codice richiede molte più istruzioni move rispetto ad ARMv8, questo significa che i vantaggi legati alle istruzioni più "compatte" degli x86-64 vengono vanificati dalla minor espressività delle istruzioni "più corte" che possono accedere a meno registri e non hanno un move "gratis" come le istruzioni a 3 operandi di ARMv8.
Ovviamente il codice x86 (a 32bit) è più compatto di x86-64, ma seguendo lo stesso ragionamento il codice a 32bit degli ARM lo è ancora di più (istruzioni ARM "classiche" + istruzioni Thumb-2 a 16bit utilizzabili nello stesso codice applicativo).
In parte ho risposto sopra. Ma, contrariamente a quello che pensi, il numero di istruzioni (dinamicamente) eseguite da x86-64 è sempre minore a quello di x86, ARMv7, ARMv8, RISC-V a 64 bit in versione G e GC, come puoi vedere dal paper che ho postato.
Paper che però è viziato, visto che per RISC-V GC hanno "casualmente" messo soltanto il numero di micro-op "fused", e non il numero di istruzioni vere e proprie. Però per il resto i dati sono affidabili. ARMv8 fa molto bene, e persino meglio di RISC-V GC "micro-op fused", ma a livello di numero di istruzioni eseguite rimane comunque sotto a x86-64.

Ciò che sorprende di questo paper è il dato relativo al "Dynamic Instruction Bytes", ossia il numero di byte di tutte le istruzioni eseguite. A parte il fatto che, al solito, il paper è biased, avendo "stranamente" gli autori rimosso tale informazione per x86 (il che non sorprende: anche dalle mie statistiche, che ho riportato sopra, la lunghezza media delle istruzioni è nettamente migliore di x86-64, assestandosi sui 3,42 byte col mio bouquet, contro i 4,05 di x86-64), è il dato relativo a x86-64 che risulta decisamente lusinghiero (cosa che francamente non avrei mai detto, visto che fa decisamente peggio di x86), superando tutte le altre architetture riportate nella tabella (sì: persino ARMv7), fatta eccezione per RISC-V GC che offre i migliori risultati. ARMv8 si difende, ma c'è un netto distacco da x86-64 (e, soprattutto, da RISC-V GC).

C'è da dire che non è affatto chiaro se per ARMv7 sia stata utilizzata anche Thumb-2, visto che non v'è traccia né menzione alcuna nel paper. Potrebbe essere anche questo frutto del bias del paper (che non mi sorprenderebbe affatto): tagliare fuori Thumb-2, che è rinomata per fare molto bene a livello di densità di codice. Preciso, però, che non puoi eseguire contemporaneamente istruzioni Thumb-2 assieme a quelle ARM normali: o esegui le une o le altre, e non puoi mischiarle. Puoi soltanto passare dalla modalità ARM a Thumb-2 (che non è soltanto a 16-bit. Anzi, la maggior parte delle istruzioni sono a 32-bit) e viceversa facendo uso di apposite istruzioni, questo sì.

In sintesi: nonostante x86-64 sia una brutta architettura per quanto riguarda la struttura degli opcode e il forzato usato di prefissi (specialmente rispetto a x86), non ne esce affatto male confrontata con architetture nuove di pacca, che non hanno dovuto portarsi dietro alcun legacy.
Quote:
Lo puoi fare se rinunci al "vantaggio" di usare gli operandi in memoria e caricando i valori da utilizzare su registri interni MOLTO PRIMA di quando poi li utilizzerai (in modo da effettuare il load out-of-order insieme ad altre istruzioni che non dipendono dal valore che stai caricando), solo che questo diventa meno vantaggioso quando si hanno meno registri.
E' un vantaggio del tutto trascurabile proprio quando hai una micro-architettura OoO.

Per il resto quello che prospetti è uno scenario ideale, dove avresti tante istruzioni da eseguire linearmente/sequenzialmente, e quindi potresti permetterti il lusso di piazzarle distanziando le load da quelle che poi ne useranno i valori.

Poi vai a prendere il codice reale, e vedi che queste gigantesche liste di istruzioni sequenziali sono alquanto rare, perché i casi comuni sono di piccoli gruppi di istruzioni intervallate/farcite di salti e da tante chiamate a subroutine. Per cui spesso capita che, invece, le load siano vicinissime o addirittura attaccate alle istruzioni che ne useranno il risultato, come puoi vedere anche negli spezzoni di codice che sono stati riportati nel paper che ho fornito.
Quote:
Inoltre lo stesso giochino di caricamento dei valori in memoria lo possono fare anche i RISC facendo molto più semplicemente ed efficientemente il renaming dei registri interni rispetto ad un CISC.
Solo che i CISC non hanno bisogno di register renaming quando usano valori immediati, come puoi vedere dalla parte di discussione che ho riportato sopra.
Quote:
Le istruzioni di prefetch "esplicito" servono per ottimizzare gli accessi alla cache, mentre le "load con molto anticipo" in architetture load-store fanno semplicemente il prefetch di valori "ottimizzato dal programmatore/compilatore".
Ma resta il fatto che se vuoi ottimizzare l'uso di istruzioni x86-64 con operandi in memoria, a livello di compilatore ti servono le istruzioni di prefetch per limitare i problemi causati dal minor numero di registri visibili al programmatore/compilatore.

Mentre questo problema non è così impattante sui RISC per la possibilità di schedulare le load con maggior anticipo tenendo tutto su registri interni.
Vedi sopra: no, servono soltanto per manipolare grosse quantità di dati.
Quote:
Questo nel caso in cui si riescano a sfruttare le istruzioni più complesse ed i modi di indirizzamento più complessi, mentre a quanto vedo, gli attuali compilatori per x86-64 quando ottimizzano ai settaggi più estremi usano le istruzioni "semplici" che hanno anche i RISC ma con molte più move tra registri.
Purtroppo è il comportamento di GCC, che non ottimizza tanto bene per x86/x64-64: altri compilatori fanno di meglio.

Ciò nonostante riesce a generare istruzioni facenti uso delle famigerate modalità d'indirizzamento indicizzate/scalate, come puoi vedere anche dal paper che ho riportato, e che fanno la differenza, specialmente rispetto a RISC-V.
Quote:
E qui si ricade nel caso di CISC in cui si privilegiano le istruzioni Risc, ma con limiti nel numero massimo di istruzioni eseguibili in parallelo.
Ma non sono i CISC che privilegiano le istruzioni più semplici: è il codice stesso che è fatto così. Poi è chiaro che ci sono anche compilatori come GCC che privilegino questo modello, ma per la loro intrinseca implementazione.
Quote:
Altrimenti quelli di ARM avrebbero implementato Aarch64 come un CISC "riscritto da zero e moderno" mentre invece hanno considerata molto più vantaggiosa un architettura "simil-RISC".
Beh, AArch64 ha molto dei CISC: un numero di istruzioni di poco inferiore rispetto a x86-64 (com'è riportato anche nel tuo paper), con modalità d'indirizzamento anche più complicate (pre-post incr/decremento), diverse istruzioni complicate (ha persino istruzioni load/store con due registri alla volta), come pure diverse istruzioni condizionali.

AArch64 è l'antitesi di RISC-V. E se consideri che ARM abbia progettato da zero quest'architettura, lascia pensare molto su quale macrofamiglia, fra RISC e CISC, abbia avuto la meglio nelle loro decisioni.
Quote:
Io aggiungerei anche che i compilatori per x86-64 tengono conto delle limitazioni di tale architettura e quindi generano sequenze di codice in cui si hanno meno pre-caricamenti di valori nei registri interni, privilegiano l'uso dei primi 8 registri, ecc. ecc.
Dipende dal compilatore, come già detto.

Ma riguardo all'uso dei registri non ci sono privilegi: vengono usati tutti e 16. Te ne accorgi subito disassemblando un qualunque binario x86-64.
Quote:
Il problema è che per arrivare al backend Risc serve una "digestione" più lunga e complessa delle istruzioni CISC, cosa che a parità di tecnologia ha il suo peso.
Senz'altro, ma bisogna vedere quanto sia questo peso. Come ho già detto altre volte, la parte legacy di x86/x86-64 ha subito poche modifiche dai tempi del PentiumPro (mi riferisco a livello micro-architetturale), e già da tempo non pesa molto, visto che ormai abbiamo chip con decine di miliardi di transistor.

Se l'obiettivo è quello di chip ridotti all'osso, allora c'è da alzare le mani: RISC-V vince a mani basse. Perfino AArch64 non potrebbe assolutamente competere, visto che si tratta di un'ISA enorme e complessa, seconda soltanto a x86-64, per l'appunto.
Quote:
Con la differenza che un Risc HA più registri disponibili per precaricare valori e che i valori immediati nella maggior parte dei casi sono piccoli oppure è vantaggioso caricarli su un registro e utilizzare più volte il registro.
SE il valore lo devi usare diverse volte.

Sul precaricamento vedi sopra.
Quote:
Alpha è morta perchè Compaq ed HP avevano deciso di puntare tutto su Itanium.
A spingere MIPS sui server era SGI, che pure essa è passata ad Itanium e poi ha fatto la fine che ha fatto. MIPS è sopravvissuto nel settore embedded ma ormai è usato principalmente in roba legacy visto che ARM ha confinato MIPS e PowerPC a nicchie ridotte di mercato.
I produttori di cpu/microcontroller embedded per roba nuova a 32bit e 64bit propongono principalmente ARM.
PowerPC resiste come architettura legacy specialmente nell'automotive ma al massimo si vedono degli shrink dei core, niente roba davvero nuova.
Infatti è un'architettura morta. Soltanto i "neo-amighisti" continuano a starci attaccati col cordone ombelicale, anziché riconoscere che i PowerPC siano morti e sepolti, per passare ad altro.
Quote:
Solo che IBM i POWER li propone solo per supercomputer e server di fascia alta, una nicchia molto remunerativa ma nicchia rimane.
Sì, ma ad alte prestazioni e con parecchi registri (l'ultima estensione SIMD ne conta ben 64). Solo che da tempo prende mazzate da x86-64.
Quote:
Forse ho capito male, ma non mi sembra che sia un vero problema (almeno per ora) visto che al momento il grosso degli utilizzi pratici sono incentrati su core con estensioni IMAC (senza floating point) oppure roba embedded compilata ad hoc, quindi sarebbe una perdita di retrocompatibilità accettabile.
Non ci sarà una vera perdita di retrocompatibilità, per quanto già detto.
I processori che hanno già implementato le estensioni attualmente standardizzate continueranno a funzionare regolarmente, ma non potranno usare le future estensioni che rimapperanno alcuni opcode.
Viceversa, quelli che useranno le future estensioni non potranno far girare i binari attuali, perché dovranno usarne di compilati appositamente per le nuove estensioni.
Quote:
In fin dei conti Risc-V non è UN unico set di istruzioni ma una famiglia di set di istruzioni.
Ed era una famiglia unita dalle estensioni già definite. Poi sono arrivate le sotto-estensioni...

C'è e ci sarà frammentazione, insomma: l'esatto opposto di quello che avevano sbandierato anni fa vantandosi del loro modello con le estensioni definite, e che adesso cercano malamente di nascondere sotto il tappeto ridefinendo a loro consumo il concetto di estensione, e creando una miriade di sotto-estensioni.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 26-12-2020, 08:38   #51
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26107
Da da arm-none-eabi-gdb.exe (x86):
Codice:
0x0072652f (7) c7042458059200                 MOV DWORD [ESP], 0x920558
0x00726536 (5) e8b5fbffff                     CALL 0x7260f0
0x0072653b (1) 90                             NOP
0x0072653c (1) 90                             NOP
0x0072653d (1) 90                             NOP
0x0072653e (1) 90                             NOP
0x0072653f (1) 90                             NOP
Da da ffmpeg_64.exe (x86-64):
Codice:
0x0000000140d554cb (8) 48c745b000000000               MOV QWORD [RBP-0x50], 0x0
0x0000000140d554d3 (5) e898faffff                     CALL 0x140d54f70
0x0000000140d554d8 (1) 90                             NOP
0x0000000140d554d9 (1) 90                             NOP
0x0000000140d554da (1) 90                             NOP
0x0000000140d554db (1) 90                             NOP
0x0000000140d554dc (1) 90                             NOP
0x0000000140d554dd (1) 90                             NOP
0x0000000140d554de (1) 90                             NOP
0x0000000140d554df (1) 90                             NOP
Vedi perché dico che GCC ottimizza (ancora!) male per x86/x64? Non sa nemmeno ottimizzare il padding delle istruzioni!!!

Questa schifezza fa aumentare in maniera consistente (perché il codice è PIENO di padding come quello, visto che i salti vengono allineati ai 16 byte) il numero di istruzioni/uop sia totali sia dinamicamente eseguite: ovvio che RISC-V guadagni su questo fronte...
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 29-12-2020, 01:52   #52
LMCH
Senior Member
 
Iscritto dal: Jan 2007
Messaggi: 5264
Quote:
Originariamente inviato da amd-novello Guarda i messaggi
wall of text versus wall of text

lol
In realtà stiamo facendo una gara tra algoritmi di generazione di wall of text.
LMCH è offline   Rispondi citando il messaggio o parte di esso
Old 29-12-2020, 02:22   #53
raxas
Senior Member
 
Iscritto dal: Oct 2002
Messaggi: 4982
ma si potrebbe avere un riassuntino degli ultimi 9 o 10 post?
tipo due righe, strette strette
__________________
____€UROPA: comunità di -PAGLIACCI €SP€RI€NTI SOLO del "B€N VIV€R€" come fosse COMANDAM€NTO nel loro PROGR€SSISMO di SCIMMI€ S€MPR€ PIU' TOTALI____Uno, Nessuno, Centomila Buchi... del mentore Pirandello, tutorialista a vuoto nonchè psico-teatralizzante nichilista e senza esiti se non il palcoscenico
raxas è offline   Rispondi citando il messaggio o parte di esso
Old 29-12-2020, 03:15   #54
LMCH
Senior Member
 
Iscritto dal: Jan 2007
Messaggi: 5264
Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Scusa, che c'entra il fatto che abbiano usato un P4? E' stato fatto soltanto per estrarre i dati delle ricerche, ma l'ABI usata è quella di x86-64, e non quella di x86, quindi register-based anziché stack-based, anche quando sono stati ridotti i registri a 12.

Ciò che era importante evidenziare è che il passaggio da 12 a 16 registri sostanzialmente non abbia inciso a livello prestazionale.
Ti credo che sul P4 non incideva, rispetto ad esempio ad uno Skylake aveva meno parallelismo interno, quindi non poteva trarre vantaggio da codice pre-parallelizzato dal compilatore sfruttando i registri disponibili.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Se le istruzioni complesse "da rischizzare" sono tutte dello stesso tipo (con Mod/RM nel caso di x86/x86-64), il costo è irrisorio: si tratta di emettere uop di load/store oltre a quella di calcolo vero e proprio, e si applica sistematicamente a tutte le istruzioni di questo tipo (basta soltanto sapere che lo siano).
Certo che si può fare ... complicando il decoder istruzioni e delegando completamente al processore delle ottimizzazioni che possono essere migliorate dal compilatore.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Opinabile. Anche coi primi processori a 32 bit ARM ha commesso degli errori, alcuni madornali: vedi il registro PC a soli 26 bit (quindi max 64MB di memoria indirizzabili), perché gli aveva aggiunto anche i bit del registro di flag/stato. Infatti è stata poi costretta a separarli con la v2 (se non erro), con una modifica all'ISA assolutamente non retro-compatibile. E' stata una visione davvero molto, molto miope.

ARM ha commesso degli errori anche con le estensioni (Thumb-EE e Jazilla che sono sostanzialmente morte, per citarne due abbastanza note).

In particolare Thumb e Thumb-2 sono l'esempio del pastrocchio che ARM ha realizzato quando ha definito la prima, mentre avrebbe potuto semplicemente prendere gli allora opcode ARM, rimuovere i 4 bit per l'esecuzione condizionale, lasciare la sola "condizione" (sempre vera) per l'esecuzione tout-court delle istruzioni, e riutilizzare le altre 15 configurazioni per definire in maniera pulita e semplice le istruzioni compatte a 16-bit. Invece è partita abbozzando malamente la prima, per poi metterci una pezza dopo con la seconda.

Ma anche qui ARM ha peccato, non avendo definito un'ISA compatta. Vedrai meglio dopo il perché, nel paper dei progettisti di RISC-V che riporterò.
Mica ho scritto che ARM non ha mai sbagliato
Semplicemente potendo ripartire quasi da zero con il set d'istruzioni a 64bit ha potuto fare scelte che Intel ed AMD non si possono manco sognare ed ha potuto basare molte decisioni sui risultati concreti ottenuti dalle diverse implementazioni RISC e CISC realizzate fino a quel punto.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Non è così, e ripeto: è perché non hai seguito l'evoluzione di quest'architettura. Infatti diverse estensioni importanti sono già state ratificate, e pure da tempo.

La grossa mancanza riguarda le estensioni vettoriali, perché sono anni che gli accademici sbattono le corna alla ricerca di qualcosa di utilizzabile concretamente nella realtà, e che non li faccia soffrire troppo nello scardinare i loro ideali di "bellezza" dell'ISA che s'erano costruiti (i famigerati soli 3 formati di opcode sono un lontano ricordo, infatti: rimangono un proclama di pura propaganda).
E meno male che a questo comitato si sono uniti diversi ingegneri provenienti da aziende, che hanno i piedi ben piantati per terra, altrimenti sarebbero state ratificate delle colossali stupidaggini, come la definizione dinamica, a runtime, del tipo di dati utilizzato dai registri vettoriali (come da originale proposta, di diversi anni fa), che avrebbe fatto piangere lacrime amare a chi avrebbe dovuto implementarle...

Ci sono anche altre estensioni già ratificate da tempo. Se non vengono usate è proprio perché al momento le aziende più interessate sono quelle che operano in ambito embedded, a cui bastano quelle istruzioni.

Anzi, quella M e A erano e sono anche di troppo (su quella C mi sono già espresso), ed è proprio il motivo per cui sono poi nate delle loro versioni castrate, aumentando di fatto la frammentazione (visto che M ed A erano già state ratificate, e non si poteva più tornare indietro).

Non lo faranno mai perché per loro l'architettura base è stata definita ed è intoccabile, incluse le istruzioni di load/store. Ti posto già qui il paper di cui ti ho parlato prima, così puoi cominciare a prendere visione di cosa ne pensano e perché sono irremovibili nel difendere le loro scelte: The Renewed Case for the Reduced Instruction Set Computer: Avoiding ISA Bloat with Macro-Op Fusion for RISC-V
Come puoi vedere già il titolo è tutto un programma, e il contenuto non si smentisce.

No. Vedi sopra. Istruzioni di load/store più avanzate sono state proposte da progetti esterni, come il PULP dell'università di Zurigo (l'estensione / progetto più diffuso, e che praticamente è diventato uno standard parallelo), ma rimarranno non standardizzate / ratificate dal comitato RISC-V.
Sarà che appartengo al lato oscuro dell'informatica (quello embedded ) ma non vedo un gran problema riguardo la "frammentazione" lato embedded visto che quello che hai descritto crea meno problemi che con gli ARM, MIPS, x86, x86-64, PowerPC ed altre architetture con evoluzioni più "contorte".

Inoltre proprio per la natura aperta di Risc V alla fine ci sarà una selezione naturale sul campo come è avvenuto con i S.O. open source dove quello attualmente più diffuso (Linux) decisamente non è il più "accademicamente puro".


Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Francamente è una ricerca che lascia il tempo che trova per le modalità utilizzate per estrarre l'elenco delle istruzioni, visto che fanno uso del comando objdump, che per limiti intrinseci disassembla anche blocchi dati, falsando le statistiche.
E' il motivo per cui, ad esempio, trovi un così elevato numero di istruzioni ADD, come puoi vedere anche dal loro sito che consente di consultare il database con le informazioni raccolte. Infatti la ADD è così inflazionata perché si tratta dell'istruzione avente 0x00 come uno dei suoi opcode: dato estremamente comune negli eseguibili, come certamente sai.
Se ci fai caso, non ho parlato delle ADD, ma delle MOV e delle modalità di indirizzamento.
E guardacaso ....

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Altri paper mostrano risultati abbastanza diversi:
https://www.strchr.com/x86_machine_code_statistics
http://citeseerx.ist.psu.edu/viewdoc...=rep1&type=pdf
http://people.umass.edu/cmutigwe/res...s%20Design.pdf
e soprattutto il paper degli autori di RISC-V che ti ho già passato che, sebbene sia ovviamente (fortemente) "biased", mostra dei dati grezzi che sono molti utili di per sé, oltre al fatto che riporta esclusivamente istruzioni reali, e soprattutto le statistiche sono di quelle dinamiche (quindi tutte e soltanto quelle eseguite realmente in quelle applicazioni) e non statiche (quelle del paper che hai postato).
... mi sembra che i paper che hai citato a tua volta contengano sostanzialmente dati concordanti riguardo l'uso delle MOV e delle modalità di indirizzamento.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Tra l'altro anche il bouquet di applicazioni che ho usato per le mie statistiche (anche statiche, sia chiaro) mostra un quadro diverso da quello del tuo paper, e più in linea con gli altri paper. Inoltre non ho disassemblato roba a caso, ma sono partito dall'entry point dell'eseguibile, e ho disassemblato tutto ciò che era possibile, tracciando le istruzioni di salto. Quindi niente spazzatura/dati grezzi disassemblati come istruzioni. Le statistiche le trovi nella mia ultima serie di articoli su Appunti Digitali, dove puoi vedere i dati della beta pubblica di Photoshop CS6, sia a 32 sia a 64-bit.
Pure nelle tue analisi risulta che x86-64 ha una lunghezza di istruzioni media di 4,3 (maggiore di 4 byte) e che le percentuali di utilizzo delle modalità di indirizzamento più complesse sono estremamente basse rispetto a quelle più comuni implementate anche da Risc V.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Ciò precisato, t'invito a leggere il paper che ho postato, e così vedrai che, sebbene la modalità d'indirizzamento indicizzata non sia così diffusa, è molto usata (dinamicamente) in alcune applicazioni ed è il motivo per cui RISC-V ha un crollo a livello prestazionale, di cui gli autori propongo una soluzione (macro-op fusion) per alleviare il problema.
Ed il problema sarebbe ?
Leggendo quella paper sostanzialmente parlano di soluzioni implementative per architetture "ad alte prestazioni" che permettono di far girare lo stesso codice anche su architetture più semplici/spartane.


Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Come vedi usare immediati porta dei vantaggi, perché NON si usano registri, e quindi non si applica il limite del register renamer.
Questo sugli x86-64 perchè sono maggiormente limitati quanto a registri disponibili, quindi le implementazioni architetturali cercano di ovviare a questo in altri modi.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
In parte ho risposto sopra. Ma, contrariamente a quello che pensi, il numero di istruzioni (dinamicamente) eseguite da x86-64 è sempre minore a quello di x86, ARMv7, ARMv8, RISC-V a 64 bit in versione G e GC, come puoi vedere dal paper che ho postato.
Paper che però è viziato, visto che per RISC-V GC hanno "casualmente" messo soltanto il numero di micro-op "fused", e non il numero di istruzioni vere e proprie. Però per il resto i dati sono affidabili. ARMv8 fa molto bene, e persino meglio di RISC-V GC "micro-op fused", ma a livello di numero di istruzioni eseguite rimane comunque sotto a x86-64.
Non era per niente "casuale", visto che, nelle attuali implementazioni di Risc V, se non erro che le istruzioni "vere e proprie" (non fused) hanno una corrispondenza 1:1 con le micro-op.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
In sintesi: nonostante x86-64 sia una brutta architettura per quanto riguarda la struttura degli opcode e il forzato usato di prefissi (specialmente rispetto a x86), non ne esce affatto male confrontata con architetture nuove di pacca, che non hanno dovuto portarsi dietro alcun legacy.
Non ne esce affatto male, ma non è la soluzione per tutti i problemi, non è un caso se pure i militari statunitensi sono molto interessati a Risc V.
Risc V di suo è ben lontano dall'essere perfetto, anzi, basta che sia "abbastanza buono" in settori dove gli x86 e gli x86-64 sono improponibili e dove l'ARM comporta costi aggiuntivi a livello di IP o limitazioni su cosa si può fare senza che ti saltino addosso gli avvocati di ARM Ltd.
LMCH è offline   Rispondi citando il messaggio o parte di esso
Old 29-12-2020, 03:26   #55
LMCH
Senior Member
 
Iscritto dal: Jan 2007
Messaggi: 5264
Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Da da arm-none-eabi-gdb.exe (x86):
Codice:
0x0072652f (7) c7042458059200                 MOV DWORD [ESP], 0x920558
0x00726536 (5) e8b5fbffff                     CALL 0x7260f0
0x0072653b (1) 90                             NOP
0x0072653c (1) 90                             NOP
0x0072653d (1) 90                             NOP
0x0072653e (1) 90                             NOP
0x0072653f (1) 90                             NOP
Da da ffmpeg_64.exe (x86-64):
Codice:
0x0000000140d554cb (8) 48c745b000000000               MOV QWORD [RBP-0x50], 0x0
0x0000000140d554d3 (5) e898faffff                     CALL 0x140d54f70
0x0000000140d554d8 (1) 90                             NOP
0x0000000140d554d9 (1) 90                             NOP
0x0000000140d554da (1) 90                             NOP
0x0000000140d554db (1) 90                             NOP
0x0000000140d554dc (1) 90                             NOP
0x0000000140d554dd (1) 90                             NOP
0x0000000140d554de (1) 90                             NOP
0x0000000140d554df (1) 90                             NOP
Vedi perché dico che GCC ottimizza (ancora!) male per x86/x64? Non sa nemmeno ottimizzare il padding delle istruzioni!!!

Questa schifezza fa aumentare in maniera consistente (perché il codice è PIENO di padding come quello, visto che i salti vengono allineati ai 16 byte) il numero di istruzioni/uop sia totali sia dinamicamente eseguite: ovvio che RISC-V guadagni su questo fronte...
Scusa ma, quale versione di GCC è stata usata e con quali switch di compilazione ?
Chiedo questo perchè mi sembra che versioni relativamente recenti di GCC ottimizzino in modo decisamente migliore di quel che si vede sopra, usando anche solo -O2 o -O3 (a meno che non vengano forzati alignment balordi con le -falign-XXXX).
LMCH è offline   Rispondi citando il messaggio o parte di esso
Old 29-12-2020, 10:23   #56
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26107
Quote:
Originariamente inviato da raxas Guarda i messaggi
ma si potrebbe avere un riassuntino degli ultimi 9 o 10 post?
tipo due righe, strette strette
Anche una soltanto: è una disquisizione su RISC vs CISC, con particolare focus su RISC-V/ARM da un lato e x86/x86-64 dall'altro.
Quote:
Originariamente inviato da LMCH Guarda i messaggi
Ti credo che sul P4 non incideva, rispetto ad esempio ad uno Skylake aveva meno parallelismo interno, quindi non poteva trarre vantaggio da codice pre-parallelizzato dal compilatore sfruttando i registri disponibili.
Rispetto a Skylake fa peggio, ma non era messo affatto male in termini di istruzioni eseguite, e quindi di parallelismo:
https://www.anandtech.com/show/1611/6

Ben 5 porte dedicate alle sole istruzioni intere/scalari, di cui due porte/ALU con throughput doppio (praticamente è come se fossero due porte ciascuna).
Quote:
Certo che si può fare ... complicando il decoder istruzioni
Poca roba, come già detto. E' di gran lunga più complicato il fatto di decodificare le istruzioni di per sé, che quello di generare un'uop anziché un'altra, o al massimo 2 uop per gestire le modalità d'indirizzamento più complesse.
Quote:
e delegando completamente al processore delle ottimizzazioni che possono essere migliorate dal compilatore.
Ne ho già parlato: nei fatti l'ottimizzazione del compilatore non serve a nulla, codice reale alla mano. Vedi i frammenti che sono stati riportati nel paper.

Lo scheduling di load & op è certamente utile, e anzi necessario, per i RISC con micro-architettura in-order.
Quote:
Mica ho scritto che ARM non ha mai sbagliato
Semplicemente potendo ripartire quasi da zero con il set d'istruzioni a 64bit ha potuto fare scelte che Intel ed AMD non si possono manco sognare ed ha potuto basare molte decisioni sui risultati concreti ottenuti dalle diverse implementazioni RISC e CISC realizzate fino a quel punto.
Ehm, no, decisamente e lo posso dire con assoluta certezza: AMD (perché è stata la prima a farlo) avrebbe potuto tirare fuori un'ISA a 64-bit togliendo di mezzo quasi tutto il legacy di IA-32/x86, e semplificando enormemente frontend/decoder e backend, pur mantenendo una vasta compatibilità a livello di codice sorgente (anche il 100%, per la verità, mentre con x86-64 la retro-compatibilità è ridotta).
Il tutto con innegabili benefici su tutti i fronti: dal minor numero di transistor utilizzati, ai consumi più ridotti, e infine alle prestazioni nettamente migliori.

In buon sostanza (!) con x86-64 avrebbe potuto fare sostanzialmente quello che ARM ha fatto con AArch64/ARMv8 (ma con risultati nettamente migliori). Solo che AMD ha preferito mettere una semplice e veloce pezza su x86, per non perdere tempo a riprogettare una soluzione migliore.
Quote:
Se ci fai caso, non ho parlato delle ADD, ma delle MOV e delle modalità di indirizzamento.
E guardacaso ....

... mi sembra che i paper che hai citato a tua volta contengano sostanzialmente dati concordanti riguardo l'uso delle MOV e delle modalità di indirizzamento.

Pure nelle tue analisi risulta che x86-64 ha una lunghezza di istruzioni media di 4,3 (maggiore di 4 byte) e che le percentuali di utilizzo delle modalità di indirizzamento più complesse sono estremamente basse rispetto a quelle più comuni implementate anche da Risc V.
Sì, sono basse a livello di numero di istruzioni statiche che le usano, ma sono molte di più in quelle dinamicamente eseguite, che poi sono quelle che fanno i numeri nei benchmark.

Il punto è proprio questo.
Quote:
Ed il problema sarebbe ?
Leggendo quella paper sostanzialmente parlano di soluzioni implementative per architetture "ad alte prestazioni" che permettono di far girare lo stesso codice anche su architetture più semplici/spartane.
Sono workaround/pezze, peraltro limitate, che complicano ulteriormente sia il frontend sia il backend.
Quote:
Questo sugli x86-64 perchè sono maggiormente limitati quanto a registri disponibili, quindi le implementazioni architetturali cercano di ovviare a questo in altri modi.
Non è questione di registri limitati: è che diverse istruzioni CISC consentono di specificare un immediato, che viene memorizzato direttamente nella uop e usato immediatamente anziché andare a pesare sul register file & sul register renamer.

Questa è un'intrinseca caratteristica dei CISC, che prescinde dal numero di registri. Infatti la mia architettura ne ha ben 32 GP, e consente ugualmente di specificare valori immediati (estendendone anche di molto l'utilizzo rispetto a x86/x86-64).
Quote:
Non era per niente "casuale",
Lo era, lo era, ma forse non ci siamo capiti.

Nel paper hanno messo soltanto le uop fused, perché sono di numero minore rispetto al numero di istruzioni, proprio perché sono fused: ossia derivano da due istruzioni che sono state fuse. Ed è, appunto, il motivo per cui hanno messo soltanto il dato delle uop fused, anziché il numero di istruzioni, come hanno fatto con tutte le altre architetture. E' un'omissione volontaria, insomma, per nascondere un dato scomodo.
Quote:
visto che, nelle attuali implementazioni di Risc V, se non erro che le istruzioni "vere e proprie" (non fused) hanno una corrispondenza 1:1 con le micro-op.
Sì. Non ce l'hanno perché sono tutte istruzioni semplici, per cui non serve dividerle in uop più semplici.
Quote:
Non ne esce affatto male, ma non è la soluzione per tutti i problemi,
No, certamente. Inoltre c'è e si può fare molto meglio, persino rimanendo in ambito CISC.
Quote:
non è un caso se pure i militari statunitensi sono molto interessati a Risc V.
Risc V di suo è ben lontano dall'essere perfetto, anzi, basta che sia "abbastanza buono" in settori dove gli x86 e gli x86-64 sono improponibili e dove l'ARM comporta costi aggiuntivi a livello di IP o limitazioni su cosa si può fare senza che ti saltino addosso gli avvocati di ARM Ltd.
Ma infatti è proprio questo il vantaggio nonché il motivo per cui molti abbracceranno RISC-V: niente licenze da pagare.
Quote:
Originariamente inviato da LMCH Guarda i messaggi
Scusa ma, quale versione di GCC è stata usata e con quali switch di compilazione ?
Chiedo questo perchè mi sembra che versioni relativamente recenti di GCC ottimizzino in modo decisamente migliore di quel che si vede sopra,
I GCC usati per quelle due sono vecchi (GCC 5.3.1 20151207 e gcc 7.1.0), ma la situazione non cambia con un recente GCC (gcc 9.3.1 (GCC) 20200328):
Codice:
0x0000000140e7ce18 (7) 488d0de1a08802                 LEA RCX, [RIP+0x288a0e1]
0x0000000140e7ce1f (5) e89cfaffff                     CALL 0x140e7c8c0
0x0000000140e7ce24 (1) 90                             NOP
0x0000000140e7ce25 (1) 90                             NOP
0x0000000140e7ce26 (1) 90                             NOP
0x0000000140e7ce27 (1) 90                             NOP
0x0000000140e7ce28 (1) 90                             NOP
0x0000000140e7ce29 (1) 90                             NOP
0x0000000140e7ce2a (1) 90                             NOP
0x0000000140e7ce2b (1) 90                             NOP
0x0000000140e7ce2c (1) 90                             NOP
0x0000000140e7ce2d (1) 90                             NOP
0x0000000140e7ce2e (1) 90                             NOP
0x0000000140e7ce2f (1) 90                             NOP
Quote:
usando anche solo -O2 o -O3 (a meno che non vengano forzati alignment balordi con le -falign-XXXX).
Per quest'ultimo GCC ho trovato questo nell'eseguibile:
configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libsrt --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-ffnvcodec --enable-cuda-llvm --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf

Trattandosi di FFMPEG mi aspetto che sia compilato almeno con -O2.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 29-12-2020, 13:16   #57
amd-novello
Senior Member
 
L'Avatar di amd-novello
 
Iscritto dal: Aug 2001
Città: Novara (NO)
Messaggi: 19637
Quote:
Originariamente inviato da raxas Guarda i messaggi
ma si potrebbe avere un riassuntino degli ultimi 9 o 10 post?
tipo due righe, strette strette
mission impossible
__________________
ASUS N76VZ +crucial m500 Dell Latitude E5430 iPad 2017 Huawei nova 5t con Very samsung tv 55m5500 ps4,wiiu
exVODA 82/18-78/16-77/13-90/11 exWIND 95/14-95/19-85/19-81/22 fritzbox 7490
su Tiscali 936/288
amd-novello è offline   Rispondi citando il messaggio o parte di esso
Old 06-01-2021, 06:39   #58
LMCH
Senior Member
 
Iscritto dal: Jan 2007
Messaggi: 5264
Innanzitutto chiedo scusa per non aver risposto prima, avevo perso di vista questa discussione.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Rispetto a Skylake fa peggio, ma non era messo affatto male in termini di istruzioni eseguite, e quindi di parallelismo:
https://www.anandtech.com/show/1611/6

Ben 5 porte dedicate alle sole istruzioni intere/scalari, di cui due porte/ALU con throughput doppio (praticamente è come se fossero due porte ciascuna).
Le due ALU con throughput doppio avevano ampiezza dimezzata rispetto alla dimensione massima di un registro intero
(16bit nelle prime versioni dei Pentium 4 che supportavano solo le istruzioni x86, 32bit nelle versioni con supporto delle x86-64) e non è che potessero processare due istruzioni per ciclo.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Poca roba, come già detto. E' di gran lunga più complicato il fatto di decodificare le istruzioni di per sé, che quello di generare un'uop anziché un'altra, o al massimo 2 uop per gestire le modalità d'indirizzamento più complesse.
Rimane il fatto che la decodifica è più complessa rispetto ad un formato più semplice e poi le eventuali due uOP sono in sequenza stretta, con minori opportunità di esecuzione senza attese dovute alla dipendenza della seconda dalla prima.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Ne ho già parlato: nei fatti l'ottimizzazione del compilatore non serve a nulla, codice reale alla mano. Vedi i frammenti che sono stati riportati nel paper.
Se ci sono pochi registri visibili al programmatore/compilatore è ovvio che è più difficile schedulare in modo ottimale.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Lo scheduling di load & op è certamente utile, e anzi necessario, per i RISC con micro-architettura in-order.
Torna dannatamente utile con qualsiasi cpu in cui ci sono pipeline e cache più lente del core.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Ehm, no, decisamente e lo posso dire con assoluta certezza: AMD (perché è stata la prima a farlo) avrebbe potuto tirare fuori un'ISA a 64-bit togliendo di mezzo quasi tutto il legacy di IA-32/x86, e semplificando enormemente frontend/decoder e backend, pur mantenendo una vasta compatibilità a livello di codice sorgente (anche il 100%, per la verità, mentre con x86-64 la retro-compatibilità è ridotta).
Il tutto con innegabili benefici su tutti i fronti: dal minor numero di transistor utilizzati, ai consumi più ridotti, e infine alle prestazioni nettamente migliori.

In buon sostanza (!) con x86-64 avrebbe potuto fare sostanzialmente quello che ARM ha fatto con AArch64/ARMv8 (ma con risultati nettamente migliori). Solo che AMD ha preferito mettere una semplice e veloce pezza su x86, per non perdere tempo a riprogettare una soluzione migliore.
C'e' una differenza fondamentale: AMD doveva uscire con una cpu a 64bit che doveva per forza essere retrocompatibile con i set di istruzioni x86 a 32bit ed a 16bit, con tutto il bagaglio delle varie estensioni x87, MMX, ed SSE2 ed al tempo stesso avere prestazioni più elevate o uguali alle cpu x86 a 32bit sue e della concorrenza.
Il compromesso migliore è quello che ha scelto (anche cosiderando cosa si poteva implementare con i processi produttivi disponibili in quel periodo).

ARM invece fino a quel momento con AArch32 da almeno più di un decennio aveva privilegiato i bassi consumi rispetto alle prestazioni e quindi era decisamente molto meno problematico avere un set di istruzioni a 64bit "tutto nuovo" e con buone prestazioni nella modalità a 32bit (ma anche li si è rivelato necessario mantenere alcune similitudini a livello di modalità di indirizzamento e "mappatura" sulle unità di esecuzione)

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Sì, sono basse a livello di numero di istruzioni statiche che le usano, ma sono molte di più in quelle dinamicamente eseguite, che poi sono quelle che fanno i numeri nei benchmark.
In pratica non è che sia così frequente indirizzare un elemento di un array (di interi, float o puntatori) contenuto dentro una struttura/record referenziata da un puntatore, usando indici che cambiano in modo non predicibile.

Di solito se c'e' di mezzo un loop, a parte l'indicizzazione iniziale all'inizializzazione del ciclo, le indicizzazioni ripetute si possono rifattorizzare in incrementi/decrementi di puntatori ottenendo codice che gira più efficientemente anche sugli x86 ed x86-64.

Inoltre se l'indicizzazione non è per elementi che sono potenze di due, si finisce con l'usare l'indirizzamento indiretto o base+offset dopo aver fatto i calcoli di indicizzazione con somme/shift/moltiplicazioni.

Se ne può fare a meno se si vuole un set d'istruzioni "base" che sia il più spartano possibile in termini di rapporto costo/prestazioni.
Infatti sebbene ARM implementi modalità di indirizzamento "complesse" per le load/store, nelle estensioni thumb queste si riducono a base+offset (dove offset può essere una costante oppure un registro) e push/pop per lo stack pointer.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Sono workaround/pezze, peraltro limitate, che complicano ulteriormente sia il frontend sia il backend.
La cosa da non dimenticare è che sono OPZIONALI, uno può scegliere di implementare un decoder ridotto all'osso oppure uno che "comprime" le istruzioni in macroOP per avere maggiori prestazioni.
Inoltre per come sono codificate le istruzioni Risc V la cosa rimane meno complicata della decodifica delle istruzioni x86-64 ... e questo considerando pure che le attuali istruzioni Risc V sono a 16bit oppure 32bit "senza fusione" ma che le specifiche prevedono già istruzioni lunghe 48, 64, .. 176 bit (più un prefisso per ulteriori istruzioni a 192bit o superiori).

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Ma infatti è proprio questo il vantaggio nonché il motivo per cui molti abbracceranno RISC-V: niente licenze da pagare.
Il vantaggio principale di Risc V non sta nel non pagare licenze, ma nel poter cambiare il fornitore del core liberamente; ci sono già adesso core Risc V utilizzabili solo con regolare licenza, senza contare le IP legate a circuiti specifici se si vogliono realizzarne implementazioni particolarmente performanti) e nell'avere un ecosistema di tool software ed hardware che non sia sotto il controllo di un singolo produttore o rivenditore di IP.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
I GCC usati per quelle due sono vecchi (GCC 5.3.1 20151207 e gcc 7.1.0), ma la situazione non cambia con un recente GCC (gcc 9.3.1 (GCC) 20200328):
Codice:
0x0000000140e7ce18 (7) 488d0de1a08802                 LEA RCX, [RIP+0x288a0e1]
0x0000000140e7ce1f (5) e89cfaffff                     CALL 0x140e7c8c0
0x0000000140e7ce24 (1) 90                             NOP
0x0000000140e7ce25 (1) 90                             NOP
0x0000000140e7ce26 (1) 90                             NOP
0x0000000140e7ce27 (1) 90                             NOP
0x0000000140e7ce28 (1) 90                             NOP
0x0000000140e7ce29 (1) 90                             NOP
0x0000000140e7ce2a (1) 90                             NOP
0x0000000140e7ce2b (1) 90                             NOP
0x0000000140e7ce2c (1) 90                             NOP
0x0000000140e7ce2d (1) 90                             NOP
0x0000000140e7ce2e (1) 90                             NOP
0x0000000140e7ce2f (1) 90                             NOP
Per quest'ultimo GCC ho trovato questo nell'eseguibile:
configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libsrt --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-ffnvcodec --enable-cuda-llvm --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf

Trattandosi di FFMPEG mi aspetto che sia compilato almeno con -O2.
Ah! Capito, la cosa è legata alle ottimizzazioni -falign-functions, -falign-labels, -falign-loops e -falign-jumps

possono essere attivate con i valori di default oppure si può optare per un tuning ad hoc per ridurre la generazione di un numero eccessivo di NOP di allineamento.

Ad esempio:

Codice:
-falign-labels
-falign-labels=n
-falign-labels=n:m
-falign-labels=n:m:n2
-falign-labels=n:m:n2:m2
n "allineamento primario" è il numero di byte a cui allineare le destinazioni dei branch.

m è il "limite di sfrido primario", ovverosia si generano NOP di allineamento ad n byte solo se si generano meno di m NOP.

n2 "allineamento secondario" è il numero di byte a cui allineare le destinazioni dei branch se l'allineamento primario fallisce a causa di sfrido superiore ad m.

m2 è il "limite di sfrido secondario", ovverosia si generano NOP di allineamento ad n2 byte solo se si generano meno di m2 NOP.

Es:
Codice:
-falign-labels=32:5:16:3
Significa allinea i target dei branch a 32byte se questo richiede al massimo 4 NOP
oppure allineali a 16 byte se questo richiede al massimo 2 NOP
oppure non tentare di allineare in tutti gli altri casi
LMCH è offline   Rispondi citando il messaggio o parte di esso
Old 06-01-2021, 10:10   #59
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26107
Quote:
Originariamente inviato da LMCH Guarda i messaggi
Innanzitutto chiedo scusa per non aver risposto prima, avevo perso di vista questa discussione.
Tranquillo: pure io rispondo quando posso.
Quote:
Le due ALU con throughput doppio avevano ampiezza dimezzata rispetto alla dimensione massima di un registro intero
(16bit nelle prime versioni dei Pentium 4 che supportavano solo le istruzioni x86, 32bit nelle versioni con supporto delle x86-64) e non è che potessero processare due istruzioni per ciclo.
Perché no?
Quote:
Rimane il fatto che la decodifica è più complessa rispetto ad un formato più semplice
Certamente, ma il costo è fisso: la decodifica per le modalità dell'indirizzamento si fa allo stesso modo, che tu debba farlo per una o centinaia di istruzioni. Il punto è questo.
Quote:
e poi le eventuali due uOP sono in sequenza stretta, con minori opportunità di esecuzione senza attese dovute alla dipendenza della seconda dalla prima.
Lasciamo che sia la logica OoO a prendersene carico, che è proprio per queste cose che è nata.
Quote:
Se ci sono pochi registri visibili al programmatore/compilatore è ovvio che è più difficile schedulare in modo ottimale.
Non è così. Se guardassi il codice reale, come ti avevo già suggerito, vedresti che è raro incontrare situazioni in cui ti puoi permettere di schedulare le istruzioni di load a debita distanza da quando verranno poi utilizzati quei dati.
Quote:
Torna dannatamente utile con qualsiasi cpu in cui ci sono pipeline e cache più lente del core.
Vero, ma è anche il motivo per cui siamo arrivati alle microarchitetture OoO, che risolvono in maniera semplice ed elegante il problema.

Il problema grosso ce l'avevano quelle in-order, come avevo già datto. E lì effettivamente con pochi registri hai difficoltà.
Ma è anche vero che, in questo caso, un'ISA CISC consente di evitare l'uso di registri addizionali (con annesse dipendenze), e inoltre avendo calcolo dell'indirizzo già integrato in uno (o più, per quelli più complicati) stage della pipeline il processore può immediatamente procedere con la lettura (e meglio ancora per la scrittura) del dato mentre in parallelo procede con la lettura degli altri registri, e quando il dato è pronto (in genere la cache L1 dati nei vecchi processori in-order è di 2-3 cicli, essendo di dimensioni ridotte) può calcolare il tutto. Non è certo un caso che i CISC in-order abbiano avuto prestazioni migliori rispetto a equivalenti RISC, come abbiamo già visto.
Quote:
C'e' una differenza fondamentale: AMD doveva uscire con una cpu a 64bit che doveva per forza essere retrocompatibile con i set di istruzioni x86 a 32bit ed a 16bit, con tutto il bagaglio delle varie estensioni x87, MMX, ed SSE2 ed al tempo stesso avere prestazioni più elevate o uguali alle cpu x86 a 32bit sue e della concorrenza.
Il compromesso migliore è quello che ha scelto (anche cosiderando cosa si poteva implementare con i processi produttivi disponibili in quel periodo).

ARM invece fino a quel momento con AArch32 da almeno più di un decennio aveva privilegiato i bassi consumi rispetto alle prestazioni e quindi era decisamente molto meno problematico avere un set di istruzioni a 64bit "tutto nuovo" e con buone prestazioni nella modalità a 32bit (ma anche li si è rivelato necessario mantenere alcune similitudini a livello di modalità di indirizzamento e "mappatura" sulle unità di esecuzione)
Con Aarch64 ARM ha conservato piena compatibilità con l'ISA a 32 bit, tant'è che possono girare applicazioni a 64 e 32 bit assieme (ovviamente per i processori che mettono a disposizione entrambe le ISA).
Idem con x86-64 che consente di far girare le vecchie applicazioni x86 assieme a quelle native.

Ovviamente entrambe le ISA a 64 bit sono incompatibili con le precedenti a 32-bit della stessa famiglia, e richiedono ricompilazioni delle applicazioni, nonché adattamenti nel caso di integrazione di assembly nel codice.

Come vedi non c'è proprio alcuna differenza. E' soltanto AMD che ha avuto fretta di tirare fuori un'ISA a 64 bit, mettendo una mala pezza su x86.
Quote:
In pratica non è che sia così frequente indirizzare un elemento di un array (di interi, float o puntatori) contenuto dentro una struttura/record referenziata da un puntatore, usando indici che cambiano in modo non predicibile.

Di solito se c'e' di mezzo un loop, a parte l'indicizzazione iniziale all'inizializzazione del ciclo, le indicizzazioni ripetute si possono rifattorizzare in incrementi/decrementi di puntatori ottenendo codice che gira più efficientemente anche sugli x86 ed x86-64.

Inoltre se l'indicizzazione non è per elementi che sono potenze di due, si finisce con l'usare l'indirizzamento indiretto o base+offset dopo aver fatto i calcoli di indicizzazione con somme/shift/moltiplicazioni.
Tutte cose che richiedono più istruzioni, e quindi inficiano sulle prestazioni nonché la densità di codice (che inficia anch'essa sulle prestazioni).

Infatti è proprio il motivo per cui, non a caso, RISC-V perde molto in quel benchmark.
Quote:
Se ne può fare a meno se si vuole un set d'istruzioni "base" che sia il più spartano possibile in termini di rapporto costo/prestazioni.
Infatti sebbene ARM implementi modalità di indirizzamento "complesse" per le load/store, nelle estensioni thumb queste si riducono a base+offset (dove offset può essere una costante oppure un registro) e push/pop per lo stack pointer.
Ma infatti il motivo è esattamente quello: hanno voluto un'ISA più spartana. E quindi ne pagano le conseguenze.

There's no free lunch...
Quote:
La cosa da non dimenticare è che sono OPZIONALI, uno può scegliere di implementare un decoder ridotto all'osso oppure uno che "comprime" le istruzioni in macroOP per avere maggiori prestazioni.
Assolutamente sì, concordo.
Quote:
Inoltre per come sono codificate le istruzioni Risc V la cosa rimane meno complicata della decodifica delle istruzioni x86-64 ... e questo considerando pure che le attuali istruzioni Risc V sono a 16bit oppure 32bit "senza fusione" ma che le specifiche prevedono già istruzioni lunghe 48, 64, .. 176 bit (più un prefisso per ulteriori istruzioni a 192bit o superiori).
Ah, non dirlo a me, che lo so bene.

Come lo sanno molto bene anche i progettisti di RISC-V, che però nei loro talk di pura propaganda che fanno alle conferenze mettono nelle slide che x86/x64 sia un'ISA a lunghezza variabile (sacrilegio!) e la cui lunghezza delle istruzioni arrivi a ben 15 byte (quasi un'intera linea di fetch!!). Squallidi ipocriti...
Quote:
Il vantaggio principale di Risc V non sta nel non pagare licenze, ma nel poter cambiare il fornitore del core liberamente; ci sono già adesso core Risc V utilizzabili solo con regolare licenza, senza contare le IP legate a circuiti specifici se si vogliono realizzarne implementazioni particolarmente performanti) e nell'avere un ecosistema di tool software ed hardware che non sia sotto il controllo di un singolo produttore o rivenditore di IP.
Beh, sì, la mancanza di licenze porta pure a questo come conseguenza.
Quote:
Ah! Capito, la cosa è legata alle ottimizzazioni -falign-functions, -falign-labels, -falign-loops e -falign-jumps

possono essere attivate con i valori di default oppure si può optare per un tuning ad hoc per ridurre la generazione di un numero eccessivo di NOP di allineamento.

Ad esempio:

Codice:
-falign-labels
-falign-labels=n
-falign-labels=n:m
-falign-labels=n:m:n2
-falign-labels=n:m:n2:m2
n "allineamento primario" è il numero di byte a cui allineare le destinazioni dei branch.

m è il "limite di sfrido primario", ovverosia si generano NOP di allineamento ad n byte solo se si generano meno di m NOP.

n2 "allineamento secondario" è il numero di byte a cui allineare le destinazioni dei branch se l'allineamento primario fallisce a causa di sfrido superiore ad m.

m2 è il "limite di sfrido secondario", ovverosia si generano NOP di allineamento ad n2 byte solo se si generano meno di m2 NOP.

Es:
Codice:
-falign-labels=32:5:16:3
Significa allinea i target dei branch a 32byte se questo richiede al massimo 4 NOP
oppure allineali a 16 byte se questo richiede al massimo 2 NOP
oppure non tentare di allineare in tutti gli altri casi
Sì, ma così è anche peggio: è un inferno!

Il codice che ho riportato prima dimostra che il compilatore ha ottimizzato per l'allineamento dopo i salti, aggiungendo le necessarie istruzioni di padding. Ed è una cosa giustissima, che ci aspetta proprio per questo.

Il problema è che il padding che emette è a dir poco orribile e, ammazza le prestazioni visto che c'è una valanga di NOP, che anche se non fanno niente... devono essere eseguite (nonché conteggiate)!

La soluzione a questo problema esiste da eoni, ed è molto semplice: in base al numero di byte di padding (che va da 1 a 15), è sufficiente utilizzare UNA apposita istruzione di NOP della lunghezza richiesta. Come fanno gli altri compilatori. Sì, perché x86/x64 hanno NOP di dimensione diversa. In questo modo il padding viene aggiunto correttamente, e a livello di esecuzione il processore esegue UNA sola istruzione NOP. E vissero tutti felici e contenti...

E il tutto senza richiedere strane e oscure ulteriori opzioni di compilazione.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys

Ultima modifica di cdimauro : 06-01-2021 alle 10:13.
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 08-01-2021, 02:31   #60
LMCH
Senior Member
 
Iscritto dal: Jan 2007
Messaggi: 5264
Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Perché no?
Perchè anche se le ALU dei Pentium 4 giravano al doppio del clock, ricevevano una singola microistruzione per ciclo di clock che agiva su un singolo registro.
Se ricordo bene, il vantaggio che davano era in termini di area e di riduzione del clock skew nell'ALU.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Certamente, ma il costo è fisso: la decodifica per le modalità dell'indirizzamento si fa allo stesso modo, che tu debba farlo per una o centinaia di istruzioni. Il punto è questo.
E' un costo che si fa sentire a livello di complessità di implementazione e del maggior numero di interdipendenze per microistruzione (a meno che non la si scomponga in due microistruzioni, vanificando l'effettivo vantaggio in termini di prestazioni finali).

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Lasciamo che sia la logica OoO a prendersene carico, che è proprio per queste cose che è nata.
L'esecuzione out-of-order non è magica, aiuta tantissimo ma più di tanto non può fare.
Basta pensare che ad esempio è possibile implementare delle stack machine con esecuzione out-of-order in teoria fantastiche come compattezza del codice, ma che poi stressano parecchio le unità di load/store.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Non è così. Se guardassi il codice reale, come ti avevo già suggerito, vedresti che è raro incontrare situazioni in cui ti puoi permettere di schedulare le istruzioni di load a debita distanza da quando verranno poi utilizzati quei dati.
Ma è più frequente schedularle "più distanti", guadagnando cicli di clock utili.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Vero, ma è anche il motivo per cui siamo arrivati alle microarchitetture OoO, che risolvono in maniera semplice ed elegante il problema.

Il problema grosso ce l'avevano quelle in-order, come avevo già datto. E lì effettivamente con pochi registri hai difficoltà.
Difatti in un sacco di applicazioni si usano ancora architetture in-order in cui ha più senso un Risc che un x86 proprio perchè si possono ottenere buone prestazioni con un implementazione relativamente semplice.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Ma è anche vero che, in questo caso, un'ISA CISC consente di evitare l'uso di registri addizionali (con annesse dipendenze), e inoltre avendo calcolo dell'indirizzo già integrato in uno (o più, per quelli più complicati) stage della pipeline il processore può immediatamente procedere con la lettura (e meglio ancora per la scrittura) del dato mentre in parallelo procede con la lettura degli altri registri, e quando il dato è pronto (in genere la cache L1 dati nei vecchi processori in-order è di 2-3 cicli, essendo di dimensioni ridotte) può calcolare il tutto. Non è certo un caso che i CISC in-order abbiano avuto prestazioni migliori rispetto a equivalenti RISC, come abbiamo già visto.
Dipende da cosa si intende per "equivalenti", stesso processo produttivo e stesso numero di gate ? E quanto potevano rispettivamente salire di clock ?

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Con Aarch64 ARM ha conservato piena compatibilità con l'ISA a 32 bit, tant'è che possono girare applicazioni a 64 e 32 bit assieme (ovviamente per i processori che mettono a disposizione entrambe le ISA).
Idem con x86-64 che consente di far girare le vecchie applicazioni x86 assieme a quelle native.
Quello che cambia è il costo di tale retrocompatibilità.
ARM A32 non aveva vincoli di retrocompatibilità quando è nato e come formato delle istruzioni era semplice e regolare, mentre l' 80386 doveva essere retrocompatibile con l' 80286 che a sua volta doveva essere retrocompatibile con l'8086 che a sua volta fu pensato per facilitare il porting di applicazioni scritte in assembly per l'8080 se ricordo bene.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Come vedi non c'è proprio alcuna differenza. E' soltanto AMD che ha avuto fretta di tirare fuori un'ISA a 64 bit, mettendo una mala pezza su x86.
Ricorda che Intel aveva già provato a sganciarsi da x86 proprio per i limiti di tale architettura per poi ritornare sui suoi passi ed aggiungere un ennesima pezza ad x86.
Aveva provato a farlo con gli iAPX 432 per poi abbandonarlo e concentrarsi sull'80386.
Poi ci ha riprovato con i "suoi" RISC i80960 (principalmente per roba embedded) ed i80860 (che tentò di piazzare come RISC per workstation e server).
Ed infine c'e' stato l'Itanium che questa volta "per retrocompatibilità" nella prima versione aveva in hardware l'equivalente in prestazioni ad un i80486.
Ma prima che Intel ritornasse sui suoi passi e mettesse la sua pezza, quella volta fu AMD a farlo e non è che abbia fatto un lavoro peggiore di Intel a riguardo.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Tutte cose che richiedono più istruzioni, e quindi inficiano sulle prestazioni nonché la densità di codice (che inficia anch'essa sulle prestazioni).

Infatti è proprio il motivo per cui, non a caso, RISC-V perde molto in quel benchmark.
Dagli tempo, al momento Risc V è ancora in evoluzione e non è che ci siano implementazioni OoO effettivamente disponibili sul mercato.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Ma infatti il motivo è esattamente quello: hanno voluto un'ISA più spartana. E quindi ne pagano le conseguenze.

There's no free lunch...
Risc V è nato come "architettura didattica e spartana" ma sono anni che sta diventando una specie di famiglia di set di istruzioni estendibili in cui l'estendibilità è nel DNA stesso del set di istruzioni.
RV32I o RV64I sono la "versione spartana" per quando ti serve una cpu senza tante pretese, poi a colpi di estensioni diventa qualcosa che si adatta a casi d'uso di ogni tipo.
Non è "perfetta", basta che sia sufficientemente versatile e con meno vincoli di quelli che si avrebbero utilizzando ARM o x86.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Ah, non dirlo a me, che lo so bene.

Come lo sanno molto bene anche i progettisti di RISC-V, che però nei loro talk di pura propaganda che fanno alle conferenze mettono nelle slide che x86/x64 sia un'ISA a lunghezza variabile (sacrilegio!) e la cui lunghezza delle istruzioni arrivi a ben 15 byte (quasi un'intera linea di fetch!!). Squallidi ipocriti...
Mi sembra che da qualche annetto si parli più della semplicità del decoder Risc V rispetto ad x86, del fatto che la lunghezza delle istruzioni la sai già con i primi bit invece di caricare prefisso dopo prefisso, ecc. ecc.
Stai ancora guardando alle origini di Risc V mentre ora di fatto è diventato altro.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Beh, sì, la mancanza di licenze porta pure a questo come conseguenza.
Spiegalo ad OpenRISC, al J-core o ad altre architetture open source, non hanno avuto lo stesso successo di Risc V.

Non è solo questione di avere un core open source, tutto l'ecosistema che si sta costruendo attorno nasce da esigenze reali a livello accademico e di R&D che stanno piano piano aprendosi la strada in altri ambiti.

Poi se avrà successo così oppure se ci sarà un Risc VI o se la cosa finirà in un ecosistema frammentato è ancora tutto da vedere, ma a livello di microcontroller e core "di servizio" mi sembra che stia facendosi strada cominciando dalla fascia bassa.

Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Sì, ma così è anche peggio: è un inferno!

Il codice che ho riportato prima dimostra che il compilatore ha ottimizzato per l'allineamento dopo i salti, aggiungendo le necessarie istruzioni di padding. Ed è una cosa giustissima, che ci aspetta proprio per questo.

Il problema è che il padding che emette è a dir poco orribile e, ammazza le prestazioni visto che c'è una valanga di NOP, che anche se non fanno niente... devono essere eseguite (nonché conteggiate)!

La soluzione a questo problema esiste da eoni, ed è molto semplice: in base al numero di byte di padding (che va da 1 a 15), è sufficiente utilizzare UNA apposita istruzione di NOP della lunghezza richiesta. Come fanno gli altri compilatori. Sì, perché x86/x64 hanno NOP di dimensione diversa. In questo modo il padding viene aggiunto correttamente, e a livello di esecuzione il processore esegue UNA sola istruzione NOP. E vissero tutti felici e contenti...

E il tutto senza richiedere strane e oscure ulteriori opzioni di compilazione.
E' almeno dalla versione 4.6.4 (del 2013) che GCC usa NOP "lunghe".
Nell'esempio su godbolt.org che ho linkato sopra, ho forzato "-falign-labels=32" in modo da rendere evidente l'inserimento di NOP "lunghi"; ma in generale a partire dal livello generico -O1 vengono attivate tutte le -falign-XXXX su valori di default che fanno scattare la generazione dei NOP (lunghi e corti a seconda delle esigenze) solo se non si genera troppo sfrido.
LMCH è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


ASUS ROG Swift OLED PG49WCD: quando QD-OLED e ultrawide si fondono ASUS ROG Swift OLED PG49WCD: quando QD-OLED e ul...
Dreame L10s Pro Ultra Heat: la pulizia di casa tutta sostanza Dreame L10s Pro Ultra Heat: la pulizia di casa t...
HONOR Magic6 Pro: come funziona Magic Portal, il modo ''intelligente'' di condividere HONOR Magic6 Pro: come funziona Magic Portal, il...
L'innovazione richiede fiducia: Workday si propone come guida nell'era dell'IA L'innovazione richiede fiducia: Workday si propo...
Recensione HONOR Pad 9: ampio display e audio top per il tablet per l'intrattenimento Recensione HONOR Pad 9: ampio display e audio to...
2 iRobot Roomba al prezzo più sco...
La tua connessione in fibra ottica potre...
Il controller DualSense per PS5 con un p...
Take-Two acquisisce Gearbox per 460 mili...
NVIDIA H100, H200 e Intel Gaudi 2 si sfi...
Lamborghini, nuovo logo e font, ora abbr...
Xbox Series X si veste di bianco, ma &eg...
La Porsche Boxster elettrica beccata in ...
L'iPad da 10,9" (Wi-Fi, 64GB) è sceso a ...
Dell, calo del mercato PC: licenziati 13...
Alfa Romeo Milano, scopriamo profilo e l...
Hisense vende un TV FHD 32 pollici con Q...
Cisco Webex anche in auto: ora è ...
Phil Schiller, il boss dell'App Store di...
Lola in Formula E insieme a Yamaha, due ...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 15:00.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Served by www2v
1