Multithreading
In informatica il multithreading indica il supporto hardware da parte di un processore di eseguire più thread. Questa tecnica si distingue da quella alla base dei sistemi multiprocessore per il fatto che i singoli thread condividono lo stesso spazio d'indirizzamento, la stessa cache e lo stesso translation lookaside buffer.
Il multithreading migliora le prestazioni dei programmi solamente quando questi sono stati sviluppati suddividendo il carico di lavoro su più thread che possono essere eseguiti in parallelo. Mentre i sistemi multiprocessore sono dotati di più unità di calcolo indipendenti per le quali l'esecuzione è effettivamente parallela, un sistema multithread invece è dotato di una singola unità di calcolo che si cerca di utilizzare al meglio eseguendo più thread nella stessa unità di calcolo. Le due tecniche sono complementari: a volte i sistemi multiprocessore implementano anche il multithreading per migliorare le prestazioni complessive del sistema.
Panoramica
modificaIl paradigma del multithreading è diventato molto popolare verso la fine degli anni novanta quando le ricerche sull'incremento dell'instruction level parallelism si sono bloccate. Allora si è spostata l'attenzione dall'eseguire un singolo programma alla massima velocità all'occupare con la massima efficienza possibile le unità di calcolo. Si è appurato che molti programmi erano composti da più flussi paralleli o potevano essere scomposti in più thread paralleli con lievi modifiche al codice sorgente. Quindi migliorando l'esecuzione di thread paralleli si poteva migliorare l'esecuzione complessiva dei programmi. Questo ha spinto lo sviluppo dei sistemi multithreading e dei sistemi multiprocessore.
Questo filone di ricerca ha portato anche delle critiche, le principali sono:
- Più thread condividono le stesse risorse come cache o translation lookaside buffer e quindi possono interferire a vicenda rallentandosi.
- Le prestazioni dei singoli thread non migliorano, ma anzi possono degradare all'aumento dei thread concorrenti.
- Il supporto hardware del multithreading e dei sistemi multiprocessori richiede anche un contributo del software, i programmi e i sistemi operativi devono essere adattati per gestire questa nuova possibilità.
Clustered Multi-Thread
modificaIl Clustered Multi-Thread è una tecnica che consente la progettazione di processori superscalari senza sacrificare tempo di ciclo, ma a costo di latenze di comunicazione maggiori.[1]
Esempi
modificaUno dei maggiori esponenti di questa architettura sono i processori Bulldozer di AMD[2]
Coarse-grained multithreading
modificaIdea di base
modificaIl multithreading coarse-grained (a grana grossa) prevede che il processore esegua un singolo thread fino a quando questo non viene bloccato da un evento che normalmente ha una elevata latenza (per esempio un cache miss), in questo caso il processore provvede a eseguire un altro thread che era pronto per l'esecuzione. Il thread di rimpiazzo rimane in esecuzione fino a quando il primo thread non è pronto per l'esecuzione.
Per esempio:
- Ciclo i: l'istruzione j del thread A viene caricata
- Ciclo i+1: l'istruzione j+1 del thread A viene caricata
- Ciclo i+2: l'istruzione j+2 del thread A viene caricata, il caricamento provoca un cache miss con corrispondente richiesta nella memoria centrale
- Ciclo i+3: il processore avvia l'esecuzione del thread B
- Ciclo i+4: l'istruzione k del thread B viene caricata
- Ciclo i+5: l'istruzione k+1 del thread B viene caricata
Concettualmente è una tecnica simile a quella presente nel multitasking cooperativo dei sistemi RTOS, in questi sistemi operativi quando un programma deve attendere un evento volontariamente cede la priorità a un altro programma pronto all'esecuzione.
Terminologia
modificaOltre che Coarse-grained multithreading viene definito Block o Cooperative multithreading.
Costo hardware
modificaIl multithreading parte dal presupposto che il passaggio tra thread avvenga in modo rapido, questa tecnica effettua il passaggio in un ciclo di clock. Al fine di ottenere questo il processore deve replicare alcune componenti per i due thread come i registri interni, il program counter e alcuni registri di stato. Anche gli adattamenti a livello software sono relativamente modesti dato che il sistema operativo deve gestire un numero modesto di thread in esecuzione contemporanea.
Esempi
modificaMolte famiglie di microcontrollori e di processori embedded implementano una gestione di più banchi di registri al fine di consentire un veloce context switch per la gestione degli interrupt. Questo può essere considerato un tipo multithreading.
- Intel Super-threading
- Intel Itanium 2
Fine-grained multithreading
modificaIdea di base
modificaUna tipologia di multithreading molto spinto prevede che il processore scambi il thread in esecuzione a ogni ciclo di clock.
Per esempio:
- Ciclo i: l'istruzione j del thread A viene caricata
- Ciclo i+1: l'istruzione k del thread B viene caricata
- Ciclo i+2: l'istruzione h del thread C viene caricata
Questa tipologia di multithreading dovrebbe rimuovere la dipendenza dai dati dei singoli thread e quindi dovrebbe azzerare o comunque ridurre gli stalli della pipeline dovuta alla dipendenza dai dati. Dato che ogni thread dovrebbe funzionare in modo indipendente i singoli thread eseguiranno programmi non correlati e quindi vi saranno poche probabilità che le istruzioni di un thread necessitino dei risultati elaborati da un'istruzione di un altro thread in esecuzione in quel momento.
Concettualmente questa tecnica è simile al multitasking preemptive presente in molti sistemi operativi. Questa analogia parte dal presupposto che ogni slot di tempo dei programmi sia posto uguale a un ciclo di clock del processore.
Terminologia
modificaQuesta tecnica di multithreading inizialmente venne chiamata barrel processing ma attualmente la terminologia moderna definisce questa tecnica come pre-emptive o interleaved o time-sliced o fine-grained multithreading.
Costo hardware
modificaIn aggiunta alle componenti indicate precedentemente questa tecnica di multithreading richiede delle componenti aggiuntive che assegnino a ogni istruzione in esecuzione un'ID che permetta di identificare il thread proprietario. Questa tecnica richiede che lo scambio tra i thread avvenga senza cicli di clock di stallo e quindi richiede hardware più sofisticato; inoltre la presenza di molti thread in esecuzione in parallelo richiede generalmente cache e TLB più capienti al fine di poter servire i vari thread in modo efficiente.
Esempi
modifica- Denelcor Heterogeneous Element Processor
- Sun Microsystems UltraSPARC T1
- Lexra NetVortex
- MIPS core 34K che implementa la Multi-Threaded ASE
- Raza Microelectronics Inc XLR
Simultaneous Multi-Threading
modificaIdea di base
modificaI moderni processori hanno più unità di calcolo che vengono utilizzate eseguendo le istruzioni dei singoli thread in parallelo. Gli attuali processori sono in grado di eseguire solamente poche istruzioni in parallelo di un singolo thread per via del ridotto parallelismo a livello di istruzioni che normalmente i thread possiedono. Quindi spesso alcune unità di elaborazione rimangono inutilizzate durante le elaborazioni. Per evitare questo il Simultaneous Multi-threading (SMT) esegue più thread in contemporanea e utilizza le istruzioni dei singoli thread per mantenere le unità di elaborazione sempre operative.
Per esempio:
- Ciclo i: istruzione j e j+1 dal thread A, istruzione k dal thread B, tutte eseguite in simultanea
- Ciclo i+1: istruzione j+2 dal thread A, istruzione k+1 dal thread B, istruzione m dal thread C, eseguite in simultanea
- Ciclo i+2: istruzione j+3 dal thread A, istruzione m+1 e m+2 dal thread C, eseguite in simultanea.
Terminologia
modificaPer distinguerlo dagli altri tipi di multithreading il termine temporal multithreading indica un tipo di multithreading che permette il completamento di istruzioni di un solo thread per ciclo di clock.
Costo hardware
modificaIn aggiunta all'hardware richiesto dal precedente tipo di multithreading, questa tecnica richiede che ogni stadio della pipeline tracci il thread d'appartenenza dell'istruzione e, dato che il processore ha più unità d'esecuzione, vi sono molte istruzioni da tracciare. Inoltre la cache e la TLB devono essere molto ampie per poter gestire un numero di thread così elevato dato che, eseguendo molte più istruzioni in parallelo, si fa un uso molto intenso delle risorse suddette.
Esempi
modifica- DEC Alpha EV8 (non terminato)
- Intel Hyper-Threading
- IBM POWER5
- Power Processing Elements del processore Cell
- Sun Microsystems UltraSPARC T2
Ricerca
modificaAttualmente la ricerca di settore si concentra su tecniche che permettano di scegliere rapidamente il thread da mandare in esecuzione in caso di stallo del thread in esecuzione. Un importante filone di ricerca è lo scheduler dei thread, che può essere gestito a livello hardware, a livello software o con un approccio misto.
Un'altra area di ricerca riguarda la tipologia di eventi che devono provocare uno scambio dei thread in esecuzione (cache miss, DMA, comunicazione inter thread, etc).
Se il multithreading replica tutti i registri visibili a livello software è possibile utilizzare il multithreading per implementare delle macchine virtuali. Ogni thread si troverebbe a gestire una propria macchina virtuale come se fosse eseguita da un processore separato e quindi potrebbe arrivare ad eseguire anche un intero sistema operativo indipendente.
Note
modifica- ^ Clustered Multithreaded Architectures – Pursuing Both IPC and Cycle Time
- ^ AMD vuole mettere paura a Intel e Nvidia: i piani per il futuro, su tomshw.it. URL consultato il 6 maggio 2015 (archiviato dall'url originale il 9 maggio 2015).
Voci correlate
modificaCollegamenti esterni
modifica- (EN) Denis Howe, multithreading, in Free On-line Dictionary of Computing. Disponibile con licenza GFDL
- Lucidi sul multithreading (PDF), su di.unito.it (archiviato il 9 giugno 2006).
- Programmazione multi-thread, su Università di Napoli (archiviato il 23 aprile 2012).