Comportamento di commutazione di contesto?

1

Devo fare una domanda che mi ha infastidito da un po 'di tempo:

Se ho un singolo core e un thread del sistema operativo, questo thread otterrà il 100% del tempo della CPU e tutto andrà bene.

Se ho un singolo core e due o più thread del sistema operativo, condivideranno il tempo della CPU utilizzando intervalli di tempo.

Quindi, le fasce temporali sono sempre lo stesso tempo, non importa quanti thread?

Quello che sto cercando di ottenere, è la quantità di lavoro che la CPU può fare lo stesso quando ho due thread o 10000 thread? Sono consapevole del fatto che ogni singolo thread procederà più lentamente poiché condividono una risorsa, ma la quantità effettiva di lavoro che la CPU può svolgere sarà la stessa?

per es.

[T1 ] [T2 ] [T1 ] [T2 ] [T1 ] [T2 ] [T1 ] [T2 ] [T1 ] [T2 ]

[T1 ] [T2 ] [T3 ] [T4 ] [T5 ] [T6 ] [T1 ] [T2 ] [T3 ] [T4 ]

----time-------------------------------------------------->
img. 1

Nell'illustrazione sopra, ci sono 2 vs 6 discussioni, ma la quantità totale di lavoro sarebbe la stessa. È vero? Oppure c'è qualcos'altro che influisce su questo quando ci sono più thread, che fanno sì che ogni slice sia più piccola o che il context switch tra i thread sia più lungo?

per es.

[T1 ] [T2 ] [T1 ] [T2 ] [T1 ] [T2 ] [T1 ] [T2 ] [T1 ] [T2 ]

[T1 ]   [T2 ]    [T3 ]    [T4 ]    [T5 ]    [T6 ]    [T1 ] 

----time-------------------------------------------------->
img. 2

Non sto chiedendo se è una buona idea usare 1000 thread ...

[Edit]

Sto cercando di chiarire quello che sto cercando di capire:

Data la quantità di tempo x, ad es. 1 minuto . E visto che il codice non usa lock o altri thread che interrompono il codice.

Se ho due thread, ci sarà y% di tempo speso per il cambio di contesto. Se ho 1000 thread, y sarà un numero maggiore ?, o sarà lo stesso del caso precedente?

    
posta Roger Johansson 01.10.2014 - 10:47
fonte

3 risposte

1

Il cambio di contesto stesso impone un sovraccarico sul sistema, perché il sistema operativo deve eseguire la contabilità su quali thread esistono, che sono in esecuzione, che sono già pronti, che hanno già ricevuto la loro giusta quota, ecc. In un design ben progettato OS questo overhead non è grande, e di solito non dipende dal numero di thread (fino ad un certo hard massimo), ma è sicuramente lì.

Tutto il resto dipende dal sistema. Ad esempio, uno scheduler può ridurre la lunghezza nominale di ogni fetta a seconda di quanti molti candidati ci sono o non può. Come sempre, una risposta ragionevole per decidere cosa fare nel tuo caso può venire solo dall'eseguire accurati test di performance sul tuo sistema .

    
risposta data 01.10.2014 - 10:53
fonte
1

Se il quantum (la durata di esecuzione di ciascun thread) è uguale, lo stesso numero di switch di contesto sarà lo stesso indipendentemente dal numero di thread (presupponendo che nessun thread sia bloccato). La quantità di tempo che ogni thread ottiene sarà influenzato, ma il sovraccarico del cambio di contesto sarà costante. Questo è in un mondo di idee; ovviamente, nel mondo reale, avrete serrature e contesa di risorse, quindi molti processi saranno in attesa di I / O o altrimenti non pronti, quindi ci sarà più overhead di commutazione del contesto, ed è possibile che la quantità di tempo trascorso a passare può superare la quantità di tempo trascorso effettivamente eseguendo il codice utente. La quantità di tempo extra dipende interamente dal carico di lavoro, motivo per cui non è possibile prevedere in genere la quantità di spese generali.

    
risposta data 01.10.2014 - 17:47
fonte
0

Anche con una singola applicazione a thread in esecuzione su un singolo computer, otterrete interruttori di contesto poiché il sistema operativo vorrà eseguire più applicazioni, analogamente a 2 app in esecuzione su un computer dual core, otterrete comunque interruttori . È solo che avere molti thread in esecuzione significa avere più opzioni di contesto.

Su Windows, le fasce orarie pianificate (o quanti) sono fisse a 10 ms (IIRC). Un thread può rinunciare a parte della sua slice dormendo, motivo per cui occasionalmente si vedono le chiamate sleep (0) nel codice. È un modo per dire "non farò niente per un po ', qualcun altro può provarlo prima che siano programmati".

Un'altra cosa che può causare un interruttore di contesto è il blocco. Se blocchi un oggetto in attesa, stai rinunciando al resto della tua porzione - nessun punto in attesa che l'oggetto venga segnalato da un thread diverso se quel thread non ha ancora avuto la possibilità di essere eseguito!

Questa è la causa principale dell'eccessiva commutazione: troppo blocco.

Quando si verifica un interruttore di contesto, la CPU deve memorizzare lo stato dei registri e caricare i registri che sono stati memorizzati per l'altro thread, probabilmente dovrà svuotare una cache per ottenere una memoria diversa in quanto l'altro thread vuole lavorare con. Questo richiede tempo e, nonostante il suo "tempo di CPU", la sua gestione domestica sprecata, ovvero il suo non speso, fa fare al tuo programma ciò che dovrebbe fare.

Ad esempio, una volta ho lavorato a un programma aziendale che impiegava più tempo a passare da un lavoro all'altro. Una volta risolto il bug di blocco, le prestazioni sono migliorate notevolmente: improvvisamente il coudl della CPU svolge un lavoro utile piuttosto che girare semplicemente tra i thread.

    
risposta data 01.10.2014 - 14:42
fonte

Leggi altre domande sui tag