10

Dire ho eseguito un semplice processo a thread singolo come quella qui sotto:Perché un singolo processo filettato viene eseguito su più processori/core?

public class SirCountALot { 
    public static void main(String[] args) { 
     int count = 0; 
     while (true) { 
      count++; 
     } 
    } 
} 

(Questo è Java perché è quello che ho familiarità con, ma ho il sospetto che non ha molta importanza)

Ho un processore i7 (4 core, o 8 contando hyperthreading), e sto usando Windows 7 a 64 bit, quindi ho attivato Sysinternals Process Explorer per esaminare l'utilizzo della CPU e, come previsto, vedo che utilizza circa il 20% di tutte le CPU disponibili.

Graph showing 20% CPU usage across all cores

Ma quando i Spostare l'opzione per mostrare 1 graph per CPU, vedo che invece di 1 dei 4 "core" in uso, l'utilizzo della CPU è diffuso in tutto i nuclei:

Graph showing erratic CPU usage on each core totaling around 20% usage

Invece quello che mi aspetterei è un core massimo, ma ciò accade solo quando imposto l'affinità per il processo su un singolo core.

Graph showing most of recent CPU usage to be confined to first core

Perché il carico di lavoro diviso nel corso dei nuclei separati? La suddivisione del carico di lavoro su diversi core non creerebbe problemi con il caching o incorre in altre penalità per le prestazioni?

E 'per il semplice motivo di impedire il surriscaldamento di un core? O c'è una ragione più profonda?

Modifica: Sono consapevole del fatto che il sistema operativo è responsabile della pianificazione, ma voglio sapere il motivo per cui "dà fastidio". Sicuramente da un punto di vista ingenuo, incollare un processo (principalmente *) a thread singolo su 1 core è il modo più semplice di fare & più efficiente?

* dico per lo più single-threaded, perché non c'è più theads qui, ma solo 2 di loro stanno facendo nulla:

Screenshot showing number of threads from Eclipse Screenshot showing number of threads in Process Explorer process properties

+2

Piccolo nitpick; dicendo che questo è un processo a thread singolo non sarà corretto. JVM genera internamente più thread per scopi di pulizia come finalizzatori, garbage collector, ecc. È possibile che per ottenere il vero lavoro svolto da ciascun thread, i thread JVM siano mappati a veri thread h/w, che potrebbero spiegare la diffusione. –

+0

Immagino che Caspar abbia inteso i thread _non-daemon_. – Santosh

+0

@ SanjayT.Sharma Sì, ho semplificato un po 'e probabilmente avrei dovuto fornire un programma di esempio in un linguaggio non gestito;) Tuttavia, come ho detto, ho il forte sospetto che non sia la JVM a farlo (e se sta mappando JVM -> HW thread e questo è responsabile, perché la mappatura cambia continuamente?) – Caspar

risposta

17

Il sistema operativo è responsabile per la pianificazione. È libero di interrompere un thread e riavviarlo su un'altra CPU. Lo farà anche se non c'è nient'altro che la macchina stia facendo.

Il processo viene spostato attorno alle CPU poiché il sistema operativo non presuppone che sia necessario continuare ad eseguire il thread sulla stessa CPU ogni volta.

Per questo motivo ho scritto una libreria per i lock thread su una CPU in modo che non si muova e non venga interrotta da altri thread. Ciò riduce la latenza e migliora il throughput ma affatica una CPU per quel thread. Questo funziona per Linux, forse puoi adattarlo per Windows. https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/Getting-started

+0

Interrompe un processo molte volte al secondo. (100/s su Linux) È più lavoro dover ricordare dove un processo è stato eseguito per l'ultima volta e provare ad assegnare quella CPU a qualsiasi altra, invece la assegna alla successiva CPU libera. –

+0

Immagino di non essere abbastanza chiaro; Sono consapevole del fatto che il sistema operativo esegue la pianificazione, e puoi vedere nel 2 ° grafico che ho impostato l'afinità per il processo in modo che utilizzi solo il primo nucleo. Quello che voglio sapere è * perché * il sistema operativo pianifica il singolo thread "attivo" su tutti i core disponibili? – Caspar

+0

La domanda inversa è perché dovremmo continuare ad assegnare un thread alla stessa CPU invece di assegnarlo alla successiva CPU libera (che è quello che fa) Utilizzare round robin funziona bene, non importa quante CPU sono occupate. Assegnare alla stessa CPU ogni volta potrebbe lasciare una CPU molto occupata (con due thread in esecuzione su di essa) mentre altre CPU sono inattive. –

1

mi aspetterei anche questo potrebbe essere fatto apposta dalla CPU e OS in modo da cercare di diffondere il carico termico del die della CPU ...

Quindi sarebbe ruotare la (unica/single) thread da core a core.

E che potrebbe certamente essere un argomento contro il tentativo di combattere questo troppo duro (soprattutto per quanto, in pratica, è spesso vedrà miglioramenti meglio semplicemente messa a punto/migliorare l'applicazione stessa in ogni caso)

+0

Interessante. Sai che Windows/Linux lo fanno di sicuro, o è un'ipotesi? (Inoltre, benvenuti a StackOverflow:) – Leeor

+0

Ho visto questo chiaramente accadendo su OSX e Windows. Mi aspetterei lo stesso per Linux ma non ho mai provato specificamente a verificarlo. – Camlin

Problemi correlati