Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Multithread su 4 core 8 thread

16 views
Skip to first unread message

Cristiano

unread,
Jan 18, 2013, 5:59:48 PM1/18/13
to
Qualcuno di voi che usa una CPU quad-core 8 thread ha mai scritto un
programma con 8 o pi� thread per verificare se la velocit� di esecuzione
rispetto al single-thread aumenta di 8 volte?

Grazie
Cristiano

Luca Pascali

unread,
Jan 19, 2013, 4:41:38 AM1/19/13
to
On Fri, 18 Jan 2013 23:59:48 +0100, Cristiano wrote:

> Qualcuno di voi che usa una CPU quad-core 8 thread ha mai scritto un
> programma con 8 o più thread per verificare se la velocità di esecuzione
> rispetto al single-thread aumenta di 8 volte?
>
> Grazie Cristiano

Sì, provato anche con molti più flussi.

E non è detto che con 8 thread paralleli la velocità di esecuzione sia 8
volte tanto.
Ci sono molte variabili in gioco che possono portare variazioni drastiche
(fino al blocco dell'applicazione) con cause sia interne che esterne al
programma.

Per farla semplice, cosa fa il programma?

Se questo dovesse generare informazioni dal nulla e buttarle nel nulla, 8
thread arriverebbero a generare 8 volte le informazioni generate da un
singolo thread (è come avere 8 programmi separati).
Se questo programma deve prendere i dati da una fonte comune e buttarli
in una destinazione comune, dovrebbero gestire l'accesso concorrente alle
risorse condivise, il che porterebbe ad avere dei momenti in cui uno o più
thread sono in attesa del proprio turno.
Più generalmente, se esistono risorse condivise, si applica il secondo
caso.
Una gestione non corretta delle risorse condivise (o delle priorità di
esecuzione) porta a situazioni di visibile degradazione o anche di
deadlock dove due o più entità sono in mutua attesa.

Altro fattore fondamentale è riassumibile con una frase che viene (o
dovrebbe) essere insegnata agli ingenieri gestionali: se una donna impiega
9 mesi per fare un bambino, 9 donne non impiegano 1 mese per fare un
bambino. (tipico esempio di lavoro non parallelizzabile)
Quindi non sempre l'approccio parallelo è applicabile o applicabile con
vantaggi.
In taluni casi, un algoritmo che gira mono-thread necessita di pesanti
modifche (finanche alla riprogettazione) per poter essere eseguito in un
contesto parallelo.

E tutto questo parlando di fattori interni.

Come fattori esterni, ci sono diverse cose che possono mettere i bastoni
tra le ruote.
Intanto sei su un sistema operativo che fa delle cose. Quindi se hai 8 cpu
a disposizione, alcune possono anche essere impegnate per fare altro.
Potresti avere delle politiche di risparmio energetico che modificano la
velocità dei processori in base a carico di lavoro e temperature,
potresti avere dei rallentamenti dovuti a letture e scritture su disco, o
scambio dati con la rete, e molto altro ancora.

Comunque il punto fondamentale è che un multithread progettato male può
essere molto inefficente, e avere prestazioni peggiori di un single
thread progettato bene. Ed è semplice progettare male un multithread.
Quindi conviene sempre chiederti: ma ti serve realmente?

PSK

Raffaele Rialdi [MVP]

unread,
Jan 19, 2013, 5:48:50 AM1/19/13
to
Cristiano wrote:
> Qualcuno di voi che usa una CPU quad-core 8 thread ha mai scritto un
> programma con 8 o piᅵ thread per verificare se la velocitᅵ di esecuzione
> rispetto al single-thread aumenta di 8 volte?
>


Aggiungo oltre a quanto giᅵ detto che core e thread sono cose molto
diverse.
I core fisici possono effettivamente arrivare a moltiplicare il lavoro
che puᅵ essere svolto completamente su altrettanti thread.
In situazioni ideali dove non ci sono latenze di I/O, dove non ci sono
risorse comuni che implicano dei lock (e quindi delle attese) puoi
arrivare a vedere che 4 thread su 4 core vanno effettivamente in
parallelo impegnando il 100% dei core.
Ovviamente ᅵ un limite non raggiungibile perchᅵ almeno 1 dei core dovrᅵ
anche svolgere un po' di lavoro per conto del sistema operativo
(scheduler, driver, altre app, etc.).

I thread invece (Intel lo chiama Hyperthreading) ᅵ il tempo recuperato
quando le istruzioni eseguite su un core implicano lo svuotamento della
cache, delle istruzioni che sono state giᅵ pronte in fetch e la branch
prediction (istruzioni che la CPU ipotizza che possano essere eseguite
nello step successivo).
Poichᅵ occorre del tempo per perparare tutte quelle cose, nel frattempo
i cicli clock del core vanno persi. Quei cicli vengono usati nelle CPU
con hyperthreading per eseguire una pipeline parallela (preparata
mentre il core faceva altro lavoro).
Ma questo tempo di esecuzione ᅵ ricavato quando il core non ha nulla da
fare e quindi non ᅵ un core supplementare ma solo una piccola
percentuale che ᅵ molto variabile a seconda di quanto spesso cache e
fetch vengono invalidate. Ricordo a memoria circa 10-20% rispetto ad un
core fisico.

Perciᅵ su su una Intel i7 con 4 core e 8 thread, potrai raggiungere uno
speed-up massimo di circa 5 volte. Sono numeri poco significativi
perchᅵ a seconda del tipo di algoritmo che fai girare potresti avere
numeri estremamente differenti.

Ultima cosa. Se hai bisogno di forte parallelizzazione ᅵ uscita una
libreria chiamata "AMP" di Microsoft che permette di spalmare i task di
esecuzione (usando la PPL, Parallel Pattern Library) su core della CPU
e anche della GPU in modo trasparente al codice che scrivi.


--
Raffaele Rialdi http://www.iamraf.net
Weblog: http://blogs.ugidotnet.org/raffaele
Microsoft MVP profile
https://mvp.support.microsoft.com/profile/raffaele
UGIdotNET - http://www.ugidotnet.org/


Cristiano

unread,
Jan 19, 2013, 7:34:37 AM1/19/13
to
On 19/01/2013 10:41, Luca Pascali wrote:
> Una gestione non corretta delle risorse condivise (o delle priorità di
> esecuzione) porta a situazioni di visibile degradazione o anche di
> deadlock dove due o più entità sono in mutua attesa.

Curare questi aspetti è, però, compito del programmatore; se il
programma è scritto male, quella povera CPU non può (e non deve) far
miracoli! :-)

Il mio interesse principale (anche in vista di un possibile acquisto di
un pc all'ultima moda) è capire se 8 o più thread *indipendenti*
(appartenenti allo stesso processo) girano 8 volte più velocemente con l'HT.
Il classico esempio di programma multi-thread che scrivo io è quello di
dare un numero in ingresso ad ognuno dei thread, questi fanno i loro
calcoli (senza accedere a risorse condivise, per quanto possibile) e al
termine, segnalano al thread principale che il calcolo è terminato, il
thread principale usa molto velocemente il risultato salvato nella
struttura di ogni thread e gli dà in pasto il numero successivo.

Io mi sarei aspettato un incremento di velocità di 8 volte, ma dopo aver
letto qualche recensione nel web, sto cominciando a capire che le cose
stanno in modo molto diverso; parlano addirittura di un misero +30%,
quando va bene.

> In taluni casi, un algoritmo che gira mono-thread necessita di pesanti
> modifche (finanche alla riprogettazione) per poter essere eseguito in un
> contesto parallelo.

Confermo. Anche volendo escludere (perché ovvie) le notevoli modifiche
da apportare al thread principale che deve assegnare i compiti ai vari
thread, la riscrittura dei thread richiede sempre un tempo abbastanza
significativo.

> Comunque il punto fondamentale è che un multithread progettato male può
> essere molto inefficente, e avere prestazioni peggiori di un single
> thread progettato bene. Ed è semplice progettare male un multithread.
> Quindi conviene sempre chiederti: ma ti serve realmente?

Io faccio un uso smodato del multi-threading nei programmi che scrivo.
E' che purtroppo mi devo accontentare del misero dual-core di 6 anni fa
(una E6400), ma nonostante questo, i programmi in cui utilizzo il
multi-thread li scrivo sempre in modo da arrivare ad un fattore 1,99...
L'idea di vedere quadruplicate le velocità di alcuni programmi di
calcolo (rispetto al 2x con l'attuale dual-core), mi piacerebbe molto,
ma sembra che le cose con l'HT non stiano così.

Cristiano

Cristiano

unread,
Jan 19, 2013, 7:51:28 AM1/19/13
to
On 19/01/2013 11:48, Raffaele Rialdi [MVP] wrote:
> Cristiano wrote:
> In situazioni ideali dove non ci sono latenze di I/O, dove non ci sono
> risorse comuni che implicano dei lock (e quindi delle attese) puoi
> arrivare a vedere che 4 thread su 4 core vanno effettivamente in
> parallelo impegnando il 100% dei core.
> Ovviamente ᅵ un limite non raggiungibile perchᅵ almeno 1 dei core dovrᅵ
> anche svolgere un po' di lavoro per conto del sistema operativo
> (scheduler, driver, altre app, etc.).

D'accordo, perᅵ vedo che nella pratica, con il mio dual-core, il limite
reale si avvicina moltissimo a quello teorico.

> I thread invece (Intel lo chiama Hyperthreading) ᅵ il tempo recuperato
> quando le istruzioni eseguite su un core implicano lo svuotamento della
> cache, delle istruzioni che sono state giᅵ pronte in fetch e la branch
> prediction (istruzioni che la CPU ipotizza che possano essere eseguite
> nello step successivo).
> Poichᅵ occorre del tempo per perparare tutte quelle cose, nel frattempo
> i cicli clock del core vanno persi. Quei cicli vengono usati nelle CPU
> con hyperthreading per eseguire una pipeline parallela (preparata mentre
> il core faceva altro lavoro).
> Ma questo tempo di esecuzione ᅵ ricavato quando il core non ha nulla da
> fare e quindi non ᅵ un core supplementare ma solo una piccola
> percentuale che ᅵ molto variabile a seconda di quanto spesso cache e
> fetch vengono invalidate. Ricordo a memoria circa 10-20% rispetto ad un
> core fisico.

Credo che sia la spiegazione piᅵ chiara e dettagliata tra tutte quelle
che ho trovato anche nel web; grazie. :-)

> Perciᅵ su su una Intel i7 con 4 core e 8 thread, potrai raggiungere uno
> speed-up massimo di circa 5 volte.

Me ne sto rendendo conto un po' alla volta. :-(

> Sono numeri poco significativi perchᅵ
> a seconda del tipo di algoritmo che fai girare potresti avere numeri
> estremamente differenti.

E purtroppo mi sa che in alcuni casi, anche con 6 o 7 thread, potrei
vedere addirittura meno di un 4x.

> Ultima cosa. Se hai bisogno di forte parallelizzazione ᅵ uscita una
> libreria chiamata "AMP" di Microsoft che permette di spalmare i task di
> esecuzione (usando la PPL, Parallel Pattern Library) su core della CPU e
> anche della GPU in modo trasparente al codice che scrivi.

Vedendo il secondo listato del link:
http://msdn.microsoft.com/en-us/library/vstudio/hh265136.aspx
non sembrerebbe proprio trasparente trasparente. :-)
E' un codice molto simile a quello che si scrive usando CUDA.

Cristiano

Raffaele Rialdi [MVP]

unread,
Jan 19, 2013, 8:25:19 AM1/19/13
to
Cristiano wrote:
> D'accordo, perᅵ vedo che nella pratica, con il mio dual-core, il limite reale
> si avvicina moltissimo a quello teorico.
>

si, il sistema operativo cerca di essere meno invasivo possibile per
cui il tempo a disposizione dei tuoi thread ᅵ quasi massimo (sempre che
altre app non ci stiano dando dentro :) )


> Credo che sia la spiegazione piᅵ chiara e dettagliata tra tutte quelle che ho
> trovato anche nel web; grazie. :-)
>

:))

> Me ne sto rendendo conto un po' alla volta. :-(
> [...]
> E purtroppo mi sa che in alcuni casi, anche con 6 o 7 thread, potrei vedere
> addirittura meno di un 4x.
>

Visto che Windows come altri OS opera con un multitasking di tipo
preemptive (cioᅵ prescinde dalla collaborazione del codice che gira nei
thread), lo scheduler fornisce un timeslot per ciascun thread. Se il
numero di thread ᅵ maggiore dei core a disposizione, ovviamente molto
tempo va sprecato nello switch invece che nell'esecuzione del codice.
Lo switch da user mode a kernel mode e viceversa ᅵ molto alto. Parliamo
di circa 5000 istruzioni assembler:
- entrare in kernel mode
- salvare i registri del thread precedente
- acquisire il dispatch spinlock (che gestisce la concorrenza tra core)
- determinare quale sia il thread successivo
- rilasciare lo spinlock
- ripristinare i registri del nuovo thread
- uscire dal kernel mode
Quindi usare tanti thread ᅵ controproducente. Comunque il vantaggio ad
usarne di piᅵ c'ᅵ nel caso questi restino fermi per operazioni di I/O.

>
> Vedendo il secondo listato del link:
> http://msdn.microsoft.com/en-us/library/vstudio/hh265136.aspx
> non sembrerebbe proprio trasparente trasparente. :-)
> E' un codice molto simile a quello che si scrive usando CUDA.
>

Il vantaggio ᅵ a reverse. Il codice che prepari per girare su GPU, cosᅵ
com'ᅵ puoi girare su multicore nel caso la GPU sia satura o non
presente.
Se ci pensi ha senso perchᅵ la GPU ha requisiti piᅵ restrittivi
rispetto alla CPU sul tipo di codice che puᅵ eseguire e questo
giustifica quel piccolo set di keyword aggiuntive / proprietarie di
VC++.
0 new messages