di  -  lunedì 16 agosto 2010

Finalmente, dopo una lunga peregrinazione tra pipeline semplici e diversificate, oggi comincia una nuova serie di articoli che andranno a spolpare un boccone molto più succulento: i processori superscalari out-of-order, ovvero le CPU che hanno spinto la computazione ad alte prestazioni negli ultimi 15 anni.

Nello scorso articolo abbiamo visto come avere pipeline diversificate sia l’idea vincente per ottenere maggiori prestazioni: ogni pipeline può essere ottimizzata per una particolare classe di istruzioni, può avere un numero di stadi diversi, ed è (in teoria) possibile avere molte più istruzioni in-flight (cioè in transito in diversi stadi della macchina) contemporaneamente. Abbiamo visto come lo scoreboarding permetta di risolvere in maniera relativamente semplice i problemi di dipendenze tra istruzioni, e come questa soluzione impatti negativamente sulle prestazioni. Infatti, pur potendo completare fuori ordine, le istruzioni devono partire in ordine di programma e devono attendere fino a che i registri sorgenti e di destinazione non sono disponibili.

Questa soluzione è poco meno “rigida” di una pipeline semplice in-order e non permette di sfruttare una larga parte dell’ILP (Instruction Level Parallelism) disponibile nei programmi. Per risolvere il problema una volta per tutte dobbiamo cambiare completamente paradigma e passare ad un’architettura dataflow.

L’idea dietro l’architettura dataflow è semplice ed elegante, ed è stata brevemente sintetizzata qui: invece di eseguire le istruzioni in ordine di programma, è sufficiente eseguirle nell’ordine in cui gli operandi diventano disponibili. È un paradigma producer-consumer: appena un’istruzione finisce l’esecuzione, producendo un valore, sblocca tutte le istruzioni che dipendono da essa. L’esecuzione procede alla massima velocità direttamente lungo l’albero delle dipendenze.

Nonostante questa architettura permetta in teoria di ottenere il massimo IPC (Instructions Per Clock) possibile, essa è irrealizzabile in pratica per motivi tecnologici: la memoria CAM e la rete di distribuzione necessarie sono così grosse e lente da rendere un tale processore totalmente inefficiente.

Ricapitolando:

  • pipeline parallele, diversificate e in-order sono pratiche da implementare, ma il controllo tramite scoreboarding è troppo rigido (sfrutta poco l’ILP, ottenendo basso IPC)
  • un’architettura dataflow permette di sfruttare tutto l’ILP disponibile in un programma, ma è irrealizzabile

La soluzione sta nel prendere il meglio dei due mondi e costruire una macchina ibrida: un processore dotato di pipeline parallele (ognuna in-order al suo interno) che operi in “modo dataflow” su una piccola porzione del codice alla volta (da qualche decina a qualche centinaio di istruzioni). Ad ogni istante il processore mantiene una Instruction Window, cioè una piccola porzione di codice sequenziale: al suo interno il programma viene eseguito in modo dataflow, mentre la Instruction Window si muove in avanti una istruzione alla volta, in-order.

Il concetto è schematizzato in figura:

È importante ricordare che il processore deve mostrare al software l’illusione che le istruzioni vengano eseguite in ordine e una alla volta. In verde sono evidenziate alcune istruzioni che sono già state eseguite “in ordine” e “una dopo l’altra” (o così il software crede). In rosso sono le istruzioni che si trovano al momento all’interno della Instruction Window: esse possono eseguire in qualunque ordine, al dataflow limit, limitate unicamente dalle dipendenze reciproche. Questo non è un problema perchè il software non vede le istruzioni in questo stato di esecuzione: mentre eseguono, le istruzioni aggiornano i registri interni ma non quelli architetturali, e quindi il software è completamente all’oscuro di questa esecuzione fuori ordine. Tuttavia le istruzioni non possono uscire dalla Instruction WIndow in ordine arbitrario: devono uscire nell’ordine del programma, per ricostruire (a beneficio del software) l’illusione di una esecuzione sequenziale. Questo risolve anche il problema di avere eccezioni precise, che avevamo incontrato con lo scoreboarding.

Questo significa che le istruzioni A, B, C, D ed E, anche se hanno finito di eseguire, non possono uscire dalla IW fino a che l’istruzione F non ha completato. A quel punto la IW scatterà in avanti di 5 posizioni e le istruzioni {A, B, C, E, F} verranno ritirate in ordine (istruzioni 3, 4, 5, 6 e 7, sequenziali). L’istruzione D, benchè completata, non può essere ritirata fino a che l’istruzione G non ha finito di eseguire, e resterà nella Instruction Window fino ad allora. Quando la IW si muove in avanti, nuove istruzioni, mostrate in grigio, entrano nella IW e cominciano ad eseguire in ordine dataflow.

Che faccia ha un processore di questo tipo? Dato che le istruzioni eseguono in ordine dataflow ci aspettiamo che le pipeline di esecuzione operino out-of-order; e dato che le istruzioni entrano ed escono dalla IW in ordine di programma, ci aspettiamo che la sezione out-of-order sia infilata in “stile sandwich” tra due sezioni in-order che mantengono l’illusione di una esecuzione sequenziale del programma.

Se prendiamo come riferimento il processore a pipeline diversificate mostrato nello scorso articolo, allora esso viene modificato in questo modo:

Prima di addentrarci nei dettagli dei singoli stadi è necessario avere visione d’insieme:

  • come sempre le istruzioni cominciano il loro viaggio dagli stadi di fetch e decode, dove le istruzioni vengono prelevate dalla memoria e decodificate per capire come manovrare gli stadi successivi
  • a questo punto le istruzioni potrebbero non essere ancora pronte pronte per eseguire (qualche operando potrebbe non essere ancora disponibile); vengono allora accodate ad un buffer di attesa (Reservation Station) dove aspettano il loro turno
  • una volta pronte le istruzioni vengono lanciate nelle pipeline di esecuzione, in ordine dataflow; il termine “out-of-order” si riferisce alle istruzioni tra di loro, non alla struttura delle pipeline di esecuzione: le singole pipeline sono strettamente in-order (ad esempio un’istruzione che entra nella terza pipeline attraverserà i 4 stadi in sequenza, uno stadio per ciclo di clock, senza scavalcare o essere scavalcata da altre istruzioni, e senza stalli)
  • una volta completata, l’istruzione viene inserita nel Reorder Buffer dove aspetta di completare in ordine (cioè uscire dalla IW in ordine di programma)

Come si vede, l’idea di fondo è piuttosto semplice. Come sempre, il diavolo è nei dettagli: progettare un sistema del genere è talmente complesso che ancora oggi, dopo decenni di studio e ingegnerizzazione di questa classe di CPU, solo una manciata di aziende sono in grado di farlo (IBM, Intel, AMD, Fujitsu con lo SPARC64, ARM col recente Cortex A9) e lo sforzo progettuale richiesto si misura in decine di milioni di ore-uomo e centinaia di milioni di dollari.

Una delle cose più curiose che qualcuno potrebbe aver notato è che le istruzioni non completano in un solo passo, ma in due se non tre passi differenti, qui indicati coi termini di finish, complete e retire. Il motivo è che le istruzioni devono prima finire di eseguire in ordine dataflow e poi uscire dalla Instruction Window in ordine di programma. Inoltre, gli store (le uniche operazioni capaci di scrivere in memoria, dato che all’interno di queste CPU “vivono” solo istruzioni simil-RISC) devono non solo terminare nel processore, ma anche aspettare che i loro dati attraversino la gerarchia di memoria fino a scrivere nella locazione corretta: per questa operazione è opportuno avere uno stadio dedicato.

Ora è il momento di immergersi un pò più a fondo nell’architettura e investigare stadi e operazioni in maggior dettaglio. La nomenclatura adottata in questo articolo viene da Shen, Lipasti, “Modern Processor Design”, forse l’unico libro che analizza in dettaglio l’architettura di processori superscalari out-of-order; altri libri e diverse compagnie usano termini differenti.

Fetch Il fetch delle istruzioni dalla Instruction Cache non è concettualmente diverso da quello delle pipeline più semplici, salvo il fatto che ora è assolutamente necessario prelevare più istruzioni per ciclo di clock: il numero di istruzioni lette dalla I-Cache limita la massima performance della CPU (non è possibile eseguire più istruzioni di quelle che sono state caricate dalla memoria e mandate in macchina). La fetch bandwidth è però limitata dalle dipendenze di controllo: bisogna eseguire i branch per sapere da dove prelevare le prossime istruzioni. Per questo motivo per i processori superscalari è fondamentale avere degli ottimi meccanismi di branch prediction, per continuare a prelevare istruzioni corrette (con alta probabilità) anche se i branch non sono ancora stati risolti. Le istruzioni lette dalla memoria vengono accumulate nel Decode Buffer, in attesa di essere decodificate.

Decode Anche in questo caso, la decodifica non è concettualmente diversa da quella di una pipeline singola; anche in questo caso, la differenza è il numero di istruzioni che devono essere decodificate. Per un processore superscalare è ovviamente necessario decodificare più istruzioni per ciclo di clock, e risolvere le dipendenze reciproche in “orizzontale” oltre che in “verticale” (cioè fra istruzioni decodificate nello stesso ciclo di clock, oltre che tra quelle decodificate in cicli successivi). Questo è particolarmente complesso per ISA CISC, dove le istruzioni hanno lunghezza diversa: come si fa a decodificare l’istruzione N+1 se non si sa dove finisce l’istruzione N? Ma visto che la necessità aguzza l’ingegno, sono state trovate tecniche per risolvere questo problema in modo molto efficace (a discapito di un maggior consumo di energia). Le istruzioni decodificate vengono accumulate nel Dispatch Buffer, in attesa di essere mandate alle unità funzionali.

Dispatch In una pipeline singola, tutte le istruzioni devono attraversare la stessa, unica pipeline. In un processore superscalare, invece, bisogna decidere verso quale unità funzionale instradare le istruzioni. Mentre le operazioni di accesso alla cache e decodifica sono eseguite in maniera centralizzata (una unità per tutte le istruzioni), le pipeline di esecuzione possono eseguire in parallelo in modo del tutto disaccoppiato: da qui la necessità di uno stadio che prelevi le istruzioni da un unico buffer di accumulo (il Dispatch Buffer) e le instradi alla corretta unità funzionale.

Reservation stations Un altro meccanismo necessario tra la decodifica e l’esecuzione di istruzioni è il buffering temporaneo in attesa degli operandi. Mentre nel Dispatch Buffer le istruzioni aspettano di essere inoltrate alla unità funzionale corretta, nelle Reservation Stations esse aspettano di avere a disposizione tutti gli operandi. Infatti è possibile che un’istruzione non possa prelevare i propri operandi dal Register File subito dopo la decodifica perchè qualche altra istruzione è in-flight nella pipeline e non ha ancora aggiornato i registri. Naturalmente sarebbe possibile stallare la decodifica fino all’aggiornamento del Register File, ma questo vanificherebbe tutti i vantaggi di questa architettura. Molto meglio stallare solo le istruzioni che non hanno ancora tutti gli operandi pronti e far proseguire le altre. Questo è il cuore dell’esecuzione fuori ordine: modificare on-the-fly l’ordine di esecuzione dall’ordine di programma all’ordine dataflow.

Issue, Execute, Finish Quando un’istruzione ha tutti gli operandi disponibili è pronta per essere lanciata nella sua pipeline. Il meccanismo di Issue sceglie, ad ogni ciclo di clock, una tra le istruzioni pronte e la manda in esecuzione. Una volta partita essa attraversa l’intera pipeline della sua unità funzionale (Functional Unit, FU) senza più stalli. Una volta uscita dall’ultimo stadio (Finish) l’istruzione aggiorna la propria entry nel Reorder Buffer, e lì attende il riordino.

Complete La Instruction Window avanza in ordine, ma le istruzioni completano fuori ordine: esse devono aspettare (dopo il Finish) nel Reorder Buffer fino a che non possono essere “completate” (cioè fatte uscire dalla IW) in ordine. A questo punto l’istruzione aggiorna i registri architetturali (cioè quelli descritti dall’ISA e visibili dal software) e termina l’esecuzione. Questo potrebbe essere vero per tutte le istruzioni, ma c’è un’ottimizzazione molto importante che può essere fatta per gli Store, e che necessita di un altro step.

Store buffer Mentre le normali istruzioni vivono e operano solo all’interno della CPU, gli Store operano anche al livello della memoria. Uno Store è completo quando ha terminato le sue operazioni nella pipeline di load/store e anche le operazioni nella gerarchia di memoria, scrivendo il suo valore nella locazione di memoria opportuna. Tuttavia non è necessario che le due operazioni vengano completate nello stesso momento. È possibile disaccoppiare le due operazioni mettendo in mezzo un buffer (come sempre!). Lo Store completa quando ha scritto il suo valore nello Store Buffer, un piccolo buffer all’interno della CPU. Da qui il valore verrà inoltrato alla memoria non appena questa sarà in grado di servire la richiesta. Una volta che la richiesta è stata servita, lo Store verrà ritirato (Retire) e sarà finito per davvero. Questo permette alla CPU di procedere alla massima velocità senza dover aspettare la memoria ad ogni Store. Questo passo si presta ad ottimizzazioni molto interessanti che permettono di ridurre la banda richiesta verso la memoria (e anche di alleviare la register pressure, particolarmente sentita in x86); presta anche però il fianco a problemi estremamente sottili e pericolosi in configurazioni multiprocessore (ad esempio: come è possibile sincronizzare l’accesso alla memoria tra i processori se il processore e la memoria vedono lo Store completarsi in due momenti diversi?).

Limiti alle prestazioni

Per la pipeline semplice avevamo identificato 3 limiti principali (qui, quinta figura):

  • dipendenze dati nei registri (anello “ALU penalty”): bisogna fornire i risultati di un’istruzione di ALU alle prossime istruzioni di ALU il più in fretta possibile
  • dipendenze dati dalla memoria (anello “load penalty”): bisogna portare i dati dalla memoria alle istruzioni che li necessitano il più in fretta possibile
  • dipendenze di controllo (anello “branch penalty”): per continuare a fetchare istruzioni bisogna risolvere i branch il più in fretta possibile

Queste limitazioni sono intrinseche in qualsiasi macchina e quindi le ritroviamo anche nei processori superscalari. A causa del cambio di architettura, queste dipendenze si trovano in posti un po’ diversi:

La risoluzione dei branch (Instruction Flow) può avvenire nel front-end o alla fine della pipeline di branch, a seconda di dove vengono prodotti il bersaglio e la decisione di salto; per un processore superscalare, tuttavia, risolvere i branch il prima possibile non è più sufficiente: la perdita di prestazione sarebbe tremenda (intuitivamente: dato che vengono eseguite N istruzioni in parallelo, per ogni ciclo di clock perso perdiamo non 1 ma N istruzioni). È assolutamente necessario spezzare le dipendenze di controllo tramite predizione dei salti, ovvero il processore deve eseguire istruzioni speculativamente, prima che il salto sia stato risolto, e deve azzeccarci molto molto spesso (più del 90% delle volte). Questo è possibile, ma richiede un intero armamentario di tecniche sofisticate.

La propagazione dei dati è simile al concetto di forwarding path visto per la pipeline semplice. Le ALU vivono nella zona di esecuzione della CPU, in quello spazio tra le Reservation Station e il Reorder Buffer. Tutti i movimenti dati tra registri non architetturali avvengono qui dentro: i valori prodotti vengono scritti nel Reorder Buffer e da qui propagati alle Reservation Station, dove le istruzioni in attesa posso “catturarli”. Esattamente come nel caso dei forwarding paths, questo permette di propagare i valori all’interno della macchina senza dover aspettare che questi vengano scritti nei registri architetturali.

La stessa cosa avviene per la memoria: i dati caricati dalla Data Cache vengono inoltrati sia al Reorder Buffer, dove i Load li stanno aspettando, sia alle Reservation Station, dove le istruzioni che dipendono da quei load li stanno aspettando. Di nuovo, riuscendo a bypassare i registri architetturali si riescono a risparmiare preziosi cicli di clock ad ogni accesso.

Conclusioni

In questo primo articolo abbiamo visto i concetti principali dietro la realizzazione di un processore superscalare out-of order e abbiamo visto come questo abbia le potenzialità per schiacciare (in termini di prestazioni) tutte le altre pipeline viste finora.

L’architettura è estremamente complessa e ogni stadio richiede tecniche complesse per raggiungere le prestazioni desiderate e non diventare il collo di bottiglia dell’intera macchina.

Nei prossimi articoli entrerò nei dettagli dei singoli stadi, analizzando le tecniche principali usate nei processori high-end che tutti ormai abbiamo nei nostri personal computer.

30 Commenti »

I commenti inseriti dai lettori di AppuntiDigitali non sono oggetto di moderazione preventiva, ma solo di eventuale filtro antispam. Qualora si ravvisi un contenuto non consono (offensivo o diffamatorio) si prega di contattare l'amministrazione di Appunti Digitali all'indirizzo info@appuntidigitali.it, specificando quale sia il commento in oggetto.

  • # 1
    phabio76
     scrive: 

    Che dire? Gli ingegneri informatici (le nuove leve della triennale) questa roba se la sognano, anzi ho il dubbio che venga del tutto sorvolata…

  • # 2
    frenzy
     scrive: 

    @phabio76

    Io ho appena finito di frequentare il terzo anno di Ingegneria Informatica e non direi proprio che questa roba “ce la sogniamo”. Anzi, tutti gli argomenti presentati nell’articolo sono stati trattati durante il corso di Calcolatori. Senza contare il fatto che questa materia viene ulteriormente “integrata” da altri corsi durante la specialistica, che la maggior parte dei laureati triennale poi frequenta.

    Non so quale sia la tua esperienza, ma qui a Bari questa roba si studia; per carità, l’Università Italiana (e nello specifico qui al Sud) è piena di problemi e mancanze, ma diamo a Cesare quel che è di Cesare, per una volta…

  • # 3
    phabio76
     scrive: 

    @frenzy
    Non voleva essere una critica a chi le Università le frequenta, quanto piuttosto al modo di proporre alcuni corsi potenzialmente bellissimi in modo asfittico, basati esclusivamente sulla teoria, con la totale mancanza di senso pratico, che corrono il rischio di far disamorare gli studenti se non c’è un professore in gamba che ci mette del suo.
    Almeno a me non basta che questi argomenti siano sull’indice del libro.
    Quanti studenti di Fisica 2 hanno mai saldato una resistenza?
    Sono dell’idea che bisogna sporcarsi le mani, auspico semplicemente una didattica un po’ più all’americana.

  • # 4
    Marco
     scrive: 

    All’universita’ di padova, al corso di architettura ci hanno fornito un calcolatore creato ad-hoc che montava un ARM per smanettarci in qualsiasi maniera possibile.

  • # 5
    Marco
     scrive: 

    All’universita’ di padova, per il corso di architettura, ci fornivano a ciascuno studente che facesse richiesta, una macchina ARM creata ad-hoc per smanettare durante le ore previste di laboratorio.

  • # 6
    Marco
     scrive: 

    [Scusate il doppione, ma ho dovuto riscriverlo perche mi aveva dato errore di “commento vuoto”]

  • # 7
    frenzy
     scrive: 

    @phabio76

    Pienamente d’accordo. Il fatto è che risulterebbe difficile farlo per tutti i corsi e ci sarebbe bisogno di laboratori degni di tal nome (soldi!!) ma prima di tutto di una riorganizzazione radicale dei corsi di laurea scientifici e tecnici attuabile solo, per dirla tutta, con un cambio netto di mentalità, liberandosi di una cultura accademica ormai superata; insomma, un bel po’ di lavoro, volontà e un bel po’ di fondi: non sto qui a spiegare i motivi per cui tutto questo in Italia non accadrà, perlomeno nell’immediato.

    Comunque chiudiamola qui, perché stiamo andando OT :D

  • # 8
    streamX
     scrive: 

    Come al solito complimenti per l’articolo.

    Volevo chiederti se potevi spiegarmi sommariamente il funzionamento dei processori che implementano differenti clock per alcuni stadi della pipeline, come ad esempio il Pentium 4.

    Grazie.

  • # 9
    Pleg (Autore del post)
     scrive: 

    @ streamX

    In realta’ a livello dell’architettura non cambia niente: tutto quello che ho scrito sopra vale tale e quale (infatti non ho mai parlato di clock nell’articolo).

    Si usano spessissimo diversi clock per diverse zone e unita’ del processore (e delle GPU, e di qualsaisi SOC, eccetera eccetera) a seconda di quello che e’ piu’ conveniente e della tecnologia a disposizione.

    Ad esempio: mi par vagamente di ricordare che il P4 aveva alcune ALU cloccate al doppio della frequenza. Questo significa che nell’implementazione circuitale di quelle ALU (che stanno nella zona di esecuzione, out-of-order) si usera’ un clock piu’ veloce, quindi bisogna stare attenti a “passare” i dati tra i due diversi domini di clock. I vari registri devono essere sincronizzati con precisione per evitare di perdere dati quando questi passano tra le zone a diverso clock.

    Altro esempio e’ la memoria: la pipeline di load/store puo’ pure viaggiare alla frequenza del core, ma la memoria non lo fa. Avrai la cache L1 che viaggia alla frequenza del core, la L2 forse si’ forse no, la L3 quasi sicuramente no, la RAM va mooolto piu’ lenta. Ad ogni passaggio bisogna stare attenti che i registri siano ben sincronizzati quando si passano i dati fra loro. Sono tecniche circuitali note.

    In processori moderni la cosa puo’ essere molto complicata, causa le tecnologie di risparmio energetico. Basta pensare che la frequenza (e a volte la tensione) dei diversi core viene modulata in tempo reale, ogni qualche decina/centinaio di millisecondi o giu’ di li’, per adattarsi al carico di lavoro. Allora puoi avere diverse zone del processore che viaggiano a velocita’ diverse, i diversi core che girano a clock diverso l’uno dall’altro, eccetera. E bisogna stare attenti alla tensione! Ad esempio se vuoi aumentare la frequenza di un core PRIMA devi aumentare la tensione, aspettare che si stabilizzi sul ring di alimentazione, POI aumentare la frequenza, stando attenti che tutta la circuiteria continui a funzionare senza intoppi (in certi casi si ferma la CPU, salva tutto lo stato in registri temporanei, si modifica tensione & frequenza, si aspetta che si stabilizzi tutto, poi si ricaricano i registri e si fa ripartire la CPU). In tutto ci vuole… qualche microsecondo :)
    E il bello e’ che in tutto questo pasticcio il software non si e’ accorto di nulla :D

  • # 10
    homero
     scrive: 

    non so se è stato fatto ma credo che il futuro dettato da intel sarebbe stato un’altro vedi architettura itanium…
    ad ogni modo l’outoforder è nata per sorvolare le limitazioni negli OS attuali, che ci trasciniamo da anni…
    se penso che sono 20 anni che linux esiste e che non si vede all’orizzonte nulla di meglio…
    in pratica l’hardware sopperisce alle limitazioni del software…
    oggi con la virtualizzazione stiamo raggiungendo un’ulteriore stadio..
    il software che emula l’hardware e l’hardware che emula il software…
    insomma è tutto un casino…che continua a funzionare male…
    solo l’IBM ha prodotto negli ultimi tempi qualcosa di decente ma questa è un’altra storia…

  • # 11
    Giuliano
     scrive: 

    Che dire…il primo commento non è assolutamente attinenta all’articolo e volto solo ad alimentare una sorta di flame…questa è l’Italia

  • # 12
    Cesare Di Mauro
     scrive: 

    @homero: ogni riferimento al flop Cell (dopo quello Itanium) immagino non sia casuale…

    Peccato che qui si parli di processori OoO, e mi sembra che l’articolo sia piuttosto chiaro riguardo ai vantaggi prestazionali che ne derivano. 8-)

  • # 13
    Marco
     scrive: 

    “solo una manciata di aziende sono in grado di farlo (IBM, Intel, AMD, Fujitsu con lo SPARC64, ARM col recente Cortex A9)”

    Ottimo articolo, come sempre!

    Vorrei aggiungere alla lista dei processori OOO almeno (quelli che mi vengono in mente):
    – ICT Loongson (architettura MIPS)
    – VIA Nano
    e i defunti HP-PA e DEC Alpha.

  • # 14
    streamX
     scrive: 

    Ho capito che avere differenti clock causa un allungamento dei tempi in fase di design/debug del chip, ma cosa comporta in termini di transistor quantificabili ?(immagino si debbano raddoppiare i generatori di clock ed i controllori del voltaggio)

    Soprattutto mi chiedo perché non vengono utilizzate mono-pipeline veloci come nel P4 per processare esclusivamente le istruzioni non parallelizzabili ?

    Grazie per la precedente risposta e scusa se ti stresso con altre domande.

  • # 15
    homero
     scrive: 

    x cdmauro
    ognuno ha le sue debolezze, io mi sposerei con itanium e cell insieme…e odio l’architettura x86 perchè ha frenato e frena l’evoluzione tecnologica delle macchine di calcolo.

    mi meraviglia che uno che abbia amato l’hardware dell’amiga non la pensi allo stesso modo…

    avevo scritto già un papiro contro l’architettura superscalare, ma per evitare di andare troppo fuori dai binari ho pensato di bene di cancellarlo…

    alla prossima!

  • # 16
    Pleg (Autore del post)
     scrive: 

    @ homero

    “ad ogni modo l’outoforder è nata per sorvolare le limitazioni negli OS attuali”

    Perche’ dici questo? Credo che le due cose siano completamente scorrelate. OOO serve a sfruttare l’ILP in hardware, e soprattutto puo’ essere implementato sotto l’ISA in modo da essere completamente trasparente al software, cosa graditissima a tutte le software house (che nno devono ricmpilare tutto il loro codice ogni volta che esce un nuovo processore, cosa che sarebbe ingestibile).

    Ci sono modi migliori per sfruttare *alcuni tipi* di ILP, come VLIW o processori vettoriali, ma non possono sfruttarlo tutto, e hanno cmq il problema che dovresti ricompilare (e in certi casi, riscrivere) il codice che avevi prima. Per certo codice OOO e’ l’unico modo per sfruttare l’ILP in modo soddisfacente, date tutte le condizioni al contorno.

  • # 17
    Pleg (Autore del post)
     scrive: 

    @ Marco

    Grazie dell’aggiunta!
    Il Godson ancora non l’ho visto da queste parti e me n’ero dimenticato :)

  • # 18
    Pleg (Autore del post)
     scrive: 

    @ streamX

    Non lavoro al layout quindi non so darti dati precisi, ma credo che in se’ in termini di area non sia granche’, si tratta di avere qualche PLL in piu’.
    L’area la perdi nell’extra routing (devi portare questi clock in giro per il circuito) e nelle strutture che ti servono a far comunicare i diversi domini di clock tra di loro. Ma non credo sia molto in termini assoluti, non ho mai sentito nessuno lamentarsi della “troppa area sprecata causa troppi clock in giro”. Ho visto chip con una trentina di diversi clock, da 50 kHz ai 600 MHz, e nessuno si e’ mai lamentato dell’extra area.

    Cmq in genere la potenza e’ piu’ importante dell’area, e con clock multipli puoi cercare di far andare le varie unita’ alla frequenza PIU’ BASSA possibile, in modo da risparmiare corrente (e quindi Watt).

    Per la seconda domanda: frequenza maggiore == consumo maggiore e maggiore temperatura, quindi bisogna stare attenti. Bisogna stare entro entrambi i limiti:
    1. il chip non deve consumare piu’ di tot Watt, se no non si riesce a dissipare il calore
    2. non ci devono essere hot-spot (punti dove localmente la temperatura supera una certa soglia, credo sia poco sopra i 100 gradi) se no bruciano i singoli transistor.

    Quindi i progettisti calibrano le pipeline tenendo conto di tutti questi parametri. Se le simulazioni dicono che usare un clock piu’ veloce su certe Unita’ Funzionali aumenta abbastanza le prestazioni senza impattare troppo sui consumi, senza causare hot-spot, e senza andare oltre il budget di capacita’ di design e debug, allora lo useranno. Se invece stimano che il guadagno prestazionale non valga la candela, allora no. E’ una decisione che prenderanno di volta in volta, e’ uno dei mille trucchi che hanno nella manica e che possono decidere di usare la’ dove serve.

  • # 19
    homero
     scrive: 

    x pleg

    ILP=ossia la programmazione a sviluppo lineare non c’entra nulla con la tecnologia superscalare…
    ad ogni modo non mi va in questa sede stare a discutere su come la tecnologia x86 nella sua evoluzione abbia rallentato lo sviluppo dell’informatica..
    ti prego di non utilizzare gli acronomi e sopratutto di abolire la dicitura “OOO” che è a dir poco stomachevole…
    sta storia degli acronimi mi fa odiare gli americani…

  • # 20
    Pleg (Autore del post)
     scrive: 

    ILP = Instruction Level Parallelism, ed e’ il tipo di parallelismo che i processori superscalari cercano di sfruttare.

  • # 21
    homero
     scrive: 

    lo avevo detto io che gli acronimi sono una dannazione per l’umanità, possono significare tantissime cose….

  • # 22
    Cesare Di Mauro
     scrive: 

    Agli acronimi corrispondono delle precise definizioni, per cui non vedo il problema: sappiamo di cosa stiamo parlando.

    Per quanto riguarda Itanium e Cell rappresentano un fallimento nei rispettivi ambiti.

    Il primo perché voleva scaricare sul compilatore l’ottimizzazione, non avendo pesato il fatto che soltanto a runtime è possibile conoscere lo stato preciso delle risorse ed eseguire le istruzioni nella maniera migliore possibile.

    Il secondo perché s’è cercato di vendere un buon stream processor come CPU general purpose.

    Infine non parteggio per x86: è un’architettura che personalmente non mi piace (rimango ancora legato ai Motorola 68000 e successori, appunto), ma non per questo nego la realtà.

    E la realtà è che si tratta di un’ISA che ha saputo evolversi nonostante le scarse premesse, e con AMD64 ha raggiunto un ottimo risultato. Inoltre i CISC venivano dati per spacciati, mentre gli ingegneri sono riusciti a inventarsi delle soluzioni geniali per spingere le prestazioni a livelli impensabili (c’erano persino esperi che negli anni ’80 affermavano che non sarebbe stato possibile implementare una pipeline) arrivando anche a superare tanti RISC anche rinomati.

  • # 23
    homero
     scrive: 

    x tutti
    gli acronimi creano confusione…
    una volta parlavo del web inteso come litteraly language…e nessuno aveva capito un tubo per 10 min….salvo poi riaversi dopo le opportune spiegazioni…
    analogamente quando si usano la maggior parte degli acronimi coniati dagli americani/anglosassoni…
    citare un acronimo ha senso solo se si inizia la propria argomentazione dispiegandolo per esteso cosa che la maggior parte non fa mai…
    il fatto di dare le cose per scontato è una pratica tipicamente dialettale, infatti io considero l’inglese un dialetto e non una lingua in quanto non è presente una precisa correlazione tra fonemi e scrittura e struttura delle parole sfido chiunque a dividere in sillabe una parola inglese…
    la sintassi è estremamente semplice proprio come quella dei dialetti e le sue forme si basano sull’uso e non su una struttura filologica…gli acronimi non sono altro che una canonizzazione dei diminutivi altra pratica dipica del dialetto…
    insomma il ragionamento proposto non sta impiedi dal punto di vista scientifico, storico, filolofico, lettarario…da qualunque parte lo guardi non riesco proprio a trovare una giustificazione…
    in passato newton per farsi ascoltare doveva scrivere in latino e cosi’ fino alla fine dell’ottocento…poi gli americani hanno abbolito tutto sentendosi i padroni del mondo…invece sono i ladri del mondo…ma questa è politica e non mi va di andarci dietro…vi basti sapere che l’italiano è una lingua, l’inglese è un dialetto acronimi compresi….
    x cdmauro
    l’amiga è un esempio virtuoso di hardware e software…
    ricordi che l’os multitask dell’amiga desktop compreso occupava 256kb con intuition e exec…
    fa piu’ di quanto fa java con 1 centesimo delle risorse…
    allora facciamo 2 conti…
    immaginati amigaOS che gira nella cache dell’itanium…altro che os realtime… anzi nella cache dell’itanium di amigaOS ce ne vanno 16…immaginate 16 virtual java machine che girano sul vostro sistema…non mi va di parlarci ma spero di aver reso l’idea di come l’architettura x86 abbia e stia frenando l’evoluzione tecnologica…

  • # 24
    Cesare Di Mauro
     scrive: 

    AmigaOS me lo ricordo molto bene, e in questo periodo sto smanettando con AROS.

    Sarebbe interessante vedere come gira AROS su Itanium, se qualcuno ne realizzasse un porting (data l’architettura di AmigaOS, non dovrebbe essere affatto difficile).

    Poi farei un bel confronto con un Duron di pari frequenza dell’Itanium, ma con una cache di almeno un ordine di grandezza inferiore. :P

  • # 25
    homero
     scrive: 

    se utilizza gcc per fare il proting allora la vedo dura…

  • # 26
    Cesare Di Mauro
     scrive: 

    Non credo che cambierebbe molto la situazione. Chi ha lavorato con Itanium e disassemblato il codice prodotto parlava sconsolato di numerose NOP presenti nei bundle delle istruzioni…

  • # 27
    Pleg (Autore del post)
     scrive: 

    Gia’, e’ inevitabile avere un bel po’ di NOP in processori VLIW. In certi casi VLIW e’ comunque ottimo, permette di avere prestazioni molto alte con hardware semplcie e risparmioso, ma per codice generico non ha funzionato bene come si era sperato.

  • # 28
    Cesare Di Mauro
     scrive: 

    Ma infatti io non ho assolutamente nulla contro i VLIW. Come ogni architettura, ha pro e contro e ambiti applicativi in cui risultano le soluzioni migliori.

    Il problema nasce quando si pretende di spacciare per universale un’architettura che ha i suoi limiti. E questo ovviamente vale per tutte quelle esistenti e future. ;)

  • # 29
    Marco
     scrive: 

    Condivido l’idea di base di HP/Intel e Transmeta di “spostare” un analizzatore statico di codice in software e mantenere un core più semplice, ma del resto i fatti sinora danno ragione a Knuth quando dice che un compilatore efficiente per tali architetture è sostanzialmente impossibile da scrivere.

    @Pleg
    Ovviamente i progettisti faranno i loro calcoli in merito (soprattutto per spingere le prestazioni del singolo core, visto il software che ci andrà a girare): quanto occupa approssimativamente in percentuale su un die e quanto incide sul consumo un’implementazione completa OOO rispetto ad una in order?
    In termini di throughput complessivo, quanto è quantificabile il vantaggio prestazionale (anche in termini di efficienza energetica) rispetto a soluzioni multicore più semplici tipo Atom o Niagara?

  • # 30
    Pleg (Autore del post)
     scrive: 

    @ Marco

    Impossibile rispondere alla prima domanda: un processore superscalare OOO non e’ un processore con pipeline singola in-order con qualcosa in piu’, ma qualcosa di fondamentalmente diverso, progettato in modo diverso in ogni sua parte. Per dire, un Nehalem non e’ un Atom con qualcosa in piu’, sono due punti molto molto lontani nello “spazio di progettazione” (intendendo con questo un fittizio spazio N-dimensionale dove ad ogni dimensione corrisponde una scelta di design, dalla profondita’ della pipeline ai parametri delle cache, ogni cosa).

    Comunque, ho appena letto oggi che Bobcat sara’ OOO ma con altri parametri vicini a quelli degli Atom di oggi. Quindi, quando esce, puoi vedere consumi e area e avere un’idea molto vaga di quello che si *puo’* fare con due architetture cosi’ diverse (a meno della differenza di nodo litografico… che pero’ e’ quasi impossibile da filtrare :)

    Per la seconda domanda, ho dei bellissimi grafici che rispondono abbastanza bene alla domanda, ma non li posso pubblicare per motivi di copyright :( sto pensando un po’ a come risolvere la questione, am se riesco a ottenere l’autorizzazione ho intenzione di scrivere un articolo proprio su quello. In breve, la risposta e’ “tanto”: tante prestazioni in piu’, e tanto consumo energetico in piu’.

    Per Niagara, invece, la storia e’ ancora diversa: e’ una macchina nata per sfruttare il Thread Level Parallelism a scapito dell’Instruction Level Parallelism, ed e’ anche una macchina estremamente semplice (il gruppo di design aveva soltanto 6 Architect e una cinquantina di progettisti, contro le migliaia di persone che Intel o AMD mettono in campo per una delle loro CPU).

Scrivi un commento!

Aggiungi il commento, oppure trackback dal tuo sito.

I commenti inseriti dai lettori di AppuntiDigitali non sono oggetto di moderazione preventiva, ma solo di eventuale filtro antispam. Qualora si ravvisi un contenuto non consono (offensivo o diffamatorio) si prega di contattare l'amministrazione di Appunti Digitali all'indirizzo info@appuntidigitali.it, specificando quale sia il commento in oggetto.