di  -  mercoledì 16 settembre 2009

A metà degli anni ’90 nel mondo delle CPU fecero il loro ingresso le cosiddette estensioni SIMD (Single Instruction, Multiple Data), prima relegate a supercomputer, che cambiarono le carte in tavola della computazione.

Questo perché si passò dalla necessità di dover eseguire più velocemente un determinato tipo di calcoli, a quella di parallelizzarli, considerato che ben si prestavano allo scopo a causa dell’applicazione delle medesime istruzioni su dati diversi (in genere contigui).

Con la versione 6 della sua architettura ARM decise di seguire le orme degli altri produttori di microprocessori, ma ovviamente lo fece a modo suo…
In un precedente articolo abbiamo visto come abbia esteso l’ISA aggiungendo, nella versione 5, il necessario per supportare delle funzionalità tipiche dei DSP .

Con la versione 6 consolida questa tendenza, aggiungendo un’istruzione di moltiplicazione & accumulazione senza segno 32×32 + 64 -> 64 bit, introducendo tre istruzioni di moltiplicazione 16×16 bit con accumulazione (a 32 o 64 bit) o senza, un altro paio che eseguono due moltiplicazioni 16×16 (sempre con accumulazione), e altre quattro 32×32 (anch’esse con accumulazione) che fanno uso soltanto dei 32 bit alti generati dall’operazione.

Ma il pezzo forte è ovviamente rappresentato dalle nuove istruzioni che operano parallelamente su più dati, e che permettono di eseguire somme o sottrazioni su coppie di interi a 16 bit, oppure su 4 interi a 8 bit alla volta. Sono state aggiunte anche un paio di istruzioni di somma e sottrazione abbastanza strane (almeno per me, che non lavoro con DSP e affini) che, penso, serviranno per particolari algoritmi (ma sufficientemente comuni da giustificarne l’implementazione).

Queste 6 istruzioni sono disponibili, a loro volta, in diverse varianti. Possono essere con o senza segno, con o senza saturazione del risultato (limitatamente al range di valori su cui operano), e infine possono lavorare con o senza segno (ma non con saturazione) dimezzando poi il risultato (per evitare overflow).

Lavorare frequentemente con dati a 8 o 16 bit porta spesso alla necessità di doverli estrarre, per cui ARM ha pensato bene di arricchire il set d’istruzioni con alcune che consentono di estrapolare (o “spacchettare” in gergo) queste quantità, estendendole con segno o con zero, e opzionalmente sommando il risultato a un altro registro.

E’ anche possibile lavorare con due valori a 8 bit da estendere a 16 bit, prelevandoli rispettivamente dai bit 0-7 e 16-23. Per tutte le operazioni di estrazione è possibile specificare una rotazione di 0, 8, 16 o 24 bit, in modo da posizionare opportunamente i dati sorgente prima dell’estrazione.

A completare l’opera sono state aggiunte varie altre istruzioni. Di particolare rilevanza sono quelle per eseguire shift (a destra o a sinistra) combinando due valori a 32 bit come se fosse un unico valore a 64 bit, scambiare l’ordine dei byte di una valore a 32 bit, eseguire la saturazione con o senza segno di valori a 8 o 16 bit, impostare l’endianess per il load & store dei dati, e infine selezionare i byte da due sorgenti a seconda degli appositi flag (GE).

I flag GE (Greather than or Equal) sono 4 e sono stati aggiunti in questa ISA perché consentono di tenere traccia di eventuali overflow (cambiamenti di segno per le operazioni su dati con segno, oppure riporti per quelle senza segno). Ognuno viene settato in base al risultato degli 8 bit a cui è assegnato (per operazioni a 16 bit i rispettivi GE assumono lo stesso valore).

Sono parecchie, quindi, le innovazioni introdotte dalla versione 6 di quest’architettura, ma non diranno molto a chi conosce estensioni SIMD di qualche altra architettura. Ordinaria amministrazione, insomma. Nell’articolo parlo, però, di “approccio” di ARM, e in seguito specifico che lo fece “a modo suo”.

Il motivo deve andare a ricercarsi nella “solita” filosofia a cui ci ha abituati ARM: piccole modifiche al core per risparmiare transistor, senza stravolgere l’architettura, e consentendo quindi di mantenere bassi i costi, il consumo, e la dissipazione di calore.

In effetti confrontando la sua soluzione con quelle implementate in altre architetture, la cosa che balza subito all’occhio è che, come aveva già fatto con le estensioni DSP, tutte queste istruzioni agiscono sui normalissimi registri della CPU.

Al contrario, le estensioni SIMD di Sun (VIS) per i suoi UltraSparc (che introdussero per la prima volta il concetto di SIMD nelle CPU più commerciali), le MMX di Intel e le 3DNow! di AMD fanno uso degli stessi registri dell’FPU, mentre la famiglia SSE ha introdotto appositi registri.

Il risultato è che l’uso di queste istruzioni per gli ARM è del tutto trasparente e “a costo zero”, mentre VIS, MMX e 3DNow! devono far uso di particolari istruzioni quando si vuole passare dalla modalità SIMD alla tradizionale FPU (e viceversa), imponendo un certo ritardo prima dell’utilizzo. Peggio ancora le SSE, che introducendo nuovi registri richiedono spazio aggiuntivo per la loro memorizzazione, con conseguente maggior aumento dei tempi di context switch.

Ovviamente anche le rose hanno le spine, e il modello adottato da ARM rimane penalizzante sotto il profilo prestazionale per tre motivi. Il primo è che usando gli stessi registri del core per funzionalità SIMD, si riduce il numero di quelli disponibili per operazioni generiche.

Il secondo, molto più pesante, è legato alla dimensione dei registri, che con soli 32 bit consente di eseguire soltanto 2 calcoli a 16 bit o 4 a 8 bit in parallelo, mentre ovviamente con registri a 64, 128 o 256 bit (e si parla già di 512 e più bit per i successori delle SSE) il numero di operazioni eseguibili in parallelo risulta di gran lunga superiore.

Il terzo, infine, riguarda il fatto che tutte le operazioni sono vincolate a interi, mentre le altre estensioni SIMD, a eccezione delle MMX, consentono di lavorare su valori in virgola mobile a singola precisione (32 bit), o addirittura doppia (64 bit), che risultano estremamente utili.

D’altra parte ricordo ancora una volta che lo scopo di ARM non è quello di andare a competere con soluzioni molto più mature e mirate alle pure prestazioni, quanto quello di offrire ai licenziatari delle sue licenze un core molto versatile che può essere impiegato anche per scopi diversi dall’elaborazione general purpose, mantenendo al contempo bassi i costi (non servono DSP o processori dedicati).

26 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
    zephyr83
     scrive: 

    Ho una piccola curiosità riguardo gli arm. Ho letto da qualche parte che facendo un paragone abbastanza “largo” gli attuali arm degli smartphone più performanti dovrebbero essere potenti quasi come un pentiumm II-III di pari frequenza.
    Quello che mi domando è se attualmente un processore ARM potrebbe arrivare a eguagliare in “generale” un core 2 duo (o un phenom II). mi piacerebbe sarebbe, grosso modo, in cosa potrebbe confrontarsi cn gli x86 e invece in cosa “perderebbe” e quanto complesso diventerebbe una CPU arm per gareggiare alla pari (o quasi) cn un x86 (i7 esclusi). Penso sia fattibile (senza pensare al “mercato”) realizzare una cpu arm per uso desktop ma quanto inciderebbe su costi e consumi?

  • # 2
    Marco
     scrive: 

    Eccellente articolo, come sempre! Immagino che sarà già in lavorazione un prossimo articolo su NEON, che pone rimedio ai difetti da te elencati allineandosi alle features di SSE, VMX e compagnia:

    “The clean, orthogonal NEON architecture works seamlessly with its own independent pipeline and register file. Key features include aligned and unaligned data access, support for integer and floating point data types, tight coupling to the ARM core, and a large register file with multiple views.”
    http://www.arm.com/miscPDFs/6629.pdf

  • # 3
    Cesare Di Mauro
     scrive: 

    Non è in lavorazione, ma ne vorrei parlare assieme alle estensioni (o ISA) Thumb. Non so quando, perché c’è il Cortex-A8 che incalza. :D

    @zephyr83: non so a quali ARM ti riferisci, ma i Pentium 2 e 3 sono dei processori superscalari abbastanza efficienti (specialmente nelle ultime incarnazioni).
    Bisognerebbe vedere quali benchmark sono stati fatti e in che modo.

    Non credo poi che gli ARM possano competere con gli x86 (siano essi Intel o AMD), perché le risorse in gioco sono troppe (ormai siamo sul miliardo e mezzo di transistor per le prossime generazioni di CPU desktop).
    Con questo numero di transistor in gioco, fa poca differenza la manciata di milioni di transistor in più degli x86 dedicata alla sezione di decodifica.

    Questo sul piano puramente prestazionale.

    Certamente le soluzioni ARM sono molto più convenienti sul piano dei consumi, e non credo avranno difficoltà ad attaccare la fascia bassa dei desktop, a parte la mancanza di compatibilità con l’ISA x86 che è il loro tallone d’Achille.

    Non penso, comunque, che ARM abbia intenzione di competere nel settore desktop.

  • # 4
    zephyr83
     scrive: 

    Il confronto che cn il pentium 2 era una cosa che avevo letto da qualche parte, chiedevo solo conferma :) credevo fosse riferito a snapdragon. Quindi dici che realizzare una versione “desktop” più complessa cn “qualche” (:D) transistor in più nn sarebbe fattibile per competere in generale cn gli x86?
    penso che per l’uso quotidiano nn ci sarebbero grosse differenze, ma in applicazioni di codifica/decodifica, rendering, compressione secondo te l’architettura ARM, in teoria, potrebbe avere qualcosa in più o ormai il divario cn gli x86 è difficilmente colmabile?
    Neanche secondo me gli arm attualmente puntano al mondo desktop ma magari piano piano potrebbero arrivarci passando prima per gli smartbook, poi netbook e infine un bel desktop di fascia media da far concorrenza a un eeebox ad esempio, da usare come “muletto” o magari mediacenter.
    nn sto parlando in ottica di mercato, so che senza l’appoggio di microsoft e delle varie grosse software house sarebbe utopistico anche pensare di insidiare addirittura apple (che ha una quota abbastanza ridotta tutto sommato), sto facendo un discorso “probabilistico”, cioè sapere se l’architettura ARM ha queste potenzialità o no. Sarebbe più facile “resuscitare” l’architettura Sparc piuttosto che far evolvere ARM (che dalla mia ignoranza in materia risultano in qualche modo “imparentati” alla lontana) per competere in ambito desktop con gli x86? Ci dobbiamo tenere gli x86 a vita? nn che abbia qualcosa contro, è solo per sapere :)
    nn mi dispiacerebbe vedere in futuro uno “scontro” cn una nuova architettura e vedere cosa riescono a tirare fuori i vari competitor!

  • # 5
    zephyr83
     scrive: 

    EDIT nn volevo dire Sparc ma Alpha!!

  • # 6
    Cesare Di Mauro
     scrive: 

    Penso che, per competere con x86, ARM dovrebbe utilizzare un numero di transistor dello stesso ordine di grandezza, impiegati più o meno per le stesse cose: cache L1, L2 e L3 (sono quelle che si “mangiano” più transistor), cache TLB, unità di calcolo intere, FP e SIMD, pipeline superscalare out-of-order con annesso apparato per lo scheduling.

    Quella della sfida con x86 è una strada che è già stata tentata da IBM (che è una multinazionale dotata di gran lunga più risorse di ARM) coi suoi PowerPC G5, e che… l’ha vista soccombere sia sul piano prestazionale che su quello dei consumi.

    Inoltre ribadisco che la mancanza di compatibilità con x86 è il più grande tallone d’Achille.

    In sostanza, perseguire la sfida sul versante desktop per ARM la vedrei una mossa azzardata, se non disastrosa.

    Sì, penso che vedremo l’architettura x86 ancora per parecchi anni, grazie anche all’introduzione della versione a 64 bit da parte di AMD.

    Ecco, questa è un’altra cosa che limita molto gli ARM per quanto riguarda l’espansione in settori come quello desktop e server: la mancanza del supporto all’elaborazione di dati, ma soprattutto allo spazio d’indirizzamento, a 64 bit.

    Fra qualche anno non ci saranno più PC a 32 bit, e inoltre tutte le altre architetture RISC sono state portate a 64 bit, mentre ARM latita. Il che non depone certamente a suo favore.

  • # 7
    Agnosta
     scrive: 

    In risposta al post 4.

    Le attuali cpu x86 hanno archittetturalmente assai poco da spartire con le capostipiti. Il cuore è RISC da un bel pezzo, associato ad un interprete, chiamiamolo così, in tempo reale. Gli “x86″ esistono da lunghissimo tempo ormai per una sola cosa, principalmente: il set di istruzioni. A parte tutte le altre caratterisitche peculiari di una piattaforma è il set di istruzioni che garantisce la compatibilità del codice macchina tra generazioni di x86 diverse, certo entro determinati limiti! Per svincolarsi bisogna fare come ha fatto Apple con Rosetta all’abbandono dei PowerPC: introdurre un emulatore software efficiente che consenta alla nuova ipotetica cpu, anche radicalmente diversa dagli x86, di eseguire velocemente il codice x86 così da consentire un distacco “morbido” dalla piattaforma precedente nell’attesa di una ampia diffusione di software nativo per la nuova piattaforma. Nulla che non si possa fare, basta volerlo e POTERLO fare! Più che altro pesa molto il “poterlo” perchè solo una casa costruttrice dalle spalle enormi (leggasi Intel, IBM…) o più Case unite in consorzio potrebbero far decollare una piattaforma del tutto nuova, con l’appoggio indispensabile, nel bene e nel male, di Microsoft.

  • # 8
    Filippo1974
     scrive: 

    Giusto per informazione:

    la presenza di operazioni di somma e sottrazione con saturazione (se sono queste le operazioni che a Cesare appaiono forse “inconsuete”) sono usatissime negli algoritmi DSP. Le implementano anche le istruzioni SIMD dei processori x86.

    L’utilizzo della saturazione è, tanto per fare un esempio, richiesto nelle implementazioni della trasformata inversa coseno (IDCT), che è un mattone fondamentale della codifica video MPEG. La catena DCT -> IDCT, con le operazioni che comporta, se implementata con aritmetica “normale” può portare spesso a situazioni di wrap-around, con il risultato che a video comparirebbero pixel di luminosità e/o colore brutalmente diversi da quelli circostanti.

    Ciao
    Filippo

  • # 9
    Cesare Di Mauro
     scrive: 

    Le operazioni con saturazione le conosco.

    Le istruzioni “strane” di cui parlavo sono soltanto un paio:

    ADDSUBX
    Does the following:
    1. Exchanges halfwords of the second operand register.
    2. Adds top halfwords and subtracts bottom halfwords.

    SUBADDX
    Does the following:
    1. Exchanges halfwords of the second operand register.
    2. Subtracts top halfwords and adds bottom halfwords.

  • # 10
    zephyr83
     scrive: 

    Leggendo le notizie di oggi sul nuovo Cortex A9 da 2 ghz dicono che dovrebbe essere più potente di un atom N270 e consumare 1.9 Watt. Come freqeuenza siamo li e anche come consumo mi sembra (l’n270 consuma qualcosina in più ma la serie Z dovrebbe rimediare). A sto punto dove va a finire il vantaggio nei consumi se cn meno transistor ma cn una frequenza simile si raggiungono gli stessi watt di un atom?
    Sicuramente in ambito netbook possono dire la loro ma a sto punto nn mi sembra così problematico per intel produrre processori x86 a bassissimo consumo!!

  • # 11
    Cesare Di Mauro
     scrive: 

    Voglio vedere in che modo misurano le prestazioni e quale chipset è stato utilizzato.

    Tanto per essere chiari, se riproducono un filmato HD col chipset che si carica della maggior parte del lavoro, tanto di cappello che l’A9 riesca a battere l’Atom col suo chipset decisamente scarso. ;)

  • # 12
    pleg
     scrive: 

    @Cesare (post 9)

    Non so per cosa vengano usate, possibili cose che mi vengono in mente sono:
    – calcolo con numeri complessi su 16 bit, potrebbero essere comode per i passaggi intermedi
    – FFT a 16 bit? Magari per qualche passaggio del butterfly puo’ far comodo scambiare le mezze word tra loro, con somma e differenza

  • # 13
    Cesare Di Mauro
     scrive: 

    La prima cosa a cui ho pensato anch’io è l’FFT, con la necessità che ha di scambiare di posto i valori, ma che ricordi ciò avviene soltanto per la prima “passata” (nei cicli successivi gli scambi avvengono fra elementi sempre più distanti). Questo sempre che la memoria non m’inganni (è passato troppo tempo da quando l’ho studiata e c’ho lavorato).

    Per quanto riguarda i numeri complessi onestamente non li avevo proprio considerati, anche perché gestirli soltanto come interi a 16 bit mi sembra poco utile.

    @zephyr83: dimenticavo una cosa. L’A9 non è soltanto superscalare, ma anche out-of-order! Mentre Atom è un processore in-order. Quindi un confronto del genere mi sembra inappropriato.

    L’A9 lo confronterei con i Sempron o i Celeron oppure con gli ultimi Nano di Via (i modelli precedenti erano in-order, come l’Atom; adesso non più), che sono anch’essi out-of-order. ;)

  • # 14
    zephyr83
     scrive: 

    @Cesare

    Bhe ma alla fine si confrontavano anche i celeron cn gli atom e pure cn i via.
    Alla fine penso che qualche confronto si possa fare soprattutto se usati su macchine che devono fare lo stesso compito (anche se nn è ancora il momento).
    Cmq nn pensavo fosse out-of-order, diventa ancora più interessante ma sn curioso di sapere anche io che tipi di test hanno effettuato e cosa sn in grado di fare in ambito multimediale e soprattutto se fa tutto la cpu o se c’è bisogno di qualche altro componente che magari aumenta il consumo!

  • # 15
    Cesare Di Mauro
     scrive: 

    E’ proprio quello di cui mi lamento: la mancanza di informazioni più precise (e rigorose).

    Per il resto è chiaro che ognuno può fare i confronti che vuole.

    A me, che sono interessato alle architetture, interessano quelli su architetture che espongano funzionalità “simili” per cercare di capire se e in che modo sono performanti, e come possono scalare. ;)

  • # 16
    zephyr83
     scrive: 

    nn riesco a trovare nessun confronto diretto cosa che cmq è resa assai difficile, l’unica sarebbe installare una distro linux su un terminale con processore arm e fare un confronto tipo con phoronix test suite. Però attualmente gli arm sui dispositivi mobili nn sn così performanti, o ci pensano “quelli di arm” oppure per gli utenti tocca aspettare ancora un bel po’.

  • # 17
    pleg
     scrive: 

    @Cesare (13)

    Si’ credo anch’io che lo swap tra parole contigue sia solo per il primo step, anche se magari ci sono delle furberie che ti permettono di usare quelle istruzioni anche negli step successivi (pura speculazione, non ho mai scritto un algoritmo FFT butterfly di mio in assembly — per fortuna :)

    Per i complessi a 16 bit… possono servire :) a inizio anno mi ci sono divertito su un DSP della TI per un corso pratico (laboratorio) di DSP.
    Hint: supponi di dover filtrare due canali audio (left/right) con lo stesso filtro FIR (ovviamente), e di fare il filtraggio in frequenza (no convoluzione). I dati in arrivo dall’ADC sono 16 bit, 44.1 kHz. Li scrivi consecutivamente in memoria, in parole di 32 bit (16 bit left, 16 bit right channels). Poi fai la FFT sulle parole da 32 bit, interpretando i 16 bit alti come parte reale e i 16 bit bassi come parte immaginaria (o viceversa, non cambia niente). Alla fine risepari, considerando i 16 bit alti (la parte reale) come il canale left, e l’altro right.
    Sorpresa: hai filtrato i due canali separatamente, anche se nella FFT li hai mischiati insieme trattandoli come un unico numero complesso :)
    E hai anche ottimizzato gli accessi alla memoria :)

    [questo trucco molto divertente mi ha permesso di filtrare 128 campioni audio in 9mila cicli di clock, mentre la soluzione dell’esercitatore ce ne metteva 13mila :) piccolo momento di gloria e godimento :) ]

  • # 18
    Cesare Di Mauro
     scrive: 

    Direi che l’esempio calzi alla perfezione. :D

    Grazie per l’interessante spunto di riflessione. :)

  • # 19
    pleg
     scrive: 

    Tra l’altro, una considerazione circuitale all’Instruction Set: avere un’istruzione che swappa le due semiword da 16 bit nella word da 32 bit non costa niente! Zero logica! Mentre farla a mano in assembly sono diverse istruzioni, che usano piu’ memoria e piu’ unita’ funzionali:

    (pseudo)assembly:
    – carica parola in R1
    – copia in R2
    – R1 > 16 (logical shift)
    – R1 | R2 (bitwise OR)

    circuito (in pseudo-VHDL):
    R1(31 downto 0)

  • # 20
    pleg
     scrive: 

    [mi ha troncato il commento in 2?!?]

    circuito (in pseudo-VHDL):
    R1(31 downto 0)

  • # 21
    pleg
     scrive: 

    [L’ha troncato di nuovo! Non posso inserire i caratteri “maggiore-uguale” di fila, vengono troncati via?!?]

    Comunque, per farla breve: a livello circuitale basta invertire i fili tra loro: zero logica, zero tempo, istruzione gratis!

  • # 22
    Cesare Di Mauro
     scrive: 

    Purtroppo wordpress fa i capricci alcune volte. :(

    Per quanto riguarda il tuo esempio, penso che dipenda tutto dall’ISA.

    Ad esempio lo stesso ARM, come puoi leggere verso la fine del mio articolo introduttivo http://www.appuntidigitali.it/4481/acorn-risc-machine-lorigine-della-specie/ , può utilizzare il suo barrel shifter all’interno delle istruzioni “a costo zero”.
    Quindi per eseguire lo swap delle 2 word a 16 bit di R1 senza toccare nessun altro registro, basterebbe la seguente istruzione: MOV R1, R1, ROL #16.

    Anche con un 68000 sarebbe sufficiente un’istruzione: ROL.L #16,D0.

    Idem con un 80386: ROL EAX,16. ;)

  • # 23
    pleg
     scrive: 

    Giusto, mi ero dimenticato del rotate ^_^;

  • # 24
    Riflessioni sull’architettura ARM - Appunti Digitali
     scrive: 

    […] Dalla prima (sostanzialmente un prototipo) e seconda versione dell’architettura a 26 bit, che l’ha lanciata, siamo passati all’analisi della terza, che ha introdotto i 32 bit, la quinta che ha fornito delle estensioni DSP, e infine la sesta che ha portato con sé quelle SIMD. […]

  • # 25
    Con Thumb-2 ARM tradisce i RISC e ritorna… ai CISC! - Appunti Digitali
     scrive: 

    […] originale. Quindi adesso è possibile sfruttare direttamente i coprocessori, le estensioni SIMD, utilizzare tutti i registri (mentre prima l’accesso diretto era riservato soltanto ai primi […]

  • # 26
    Cortex-A8: una nuova via per ARM - Appunti Digitali
     scrive: 

    […] punto di rottura col passato rappresentato dal fatto che l’approccio usato in precedenza per implementare funzionalità di tipo SIMD è stato molto più “morbido”, modificando il core aggiungendo nuovi flag e istruzioni […]

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.