Come posso avere 1805 thread quando ho solo 4 CPU virtuali?


10

Mi chiedevo se qualcuno potesse spiegarmi come nel mio Activity Monitor dice che attualmente ho 1805 thread Schermata di OS X Activity Monitor

Ma ho solo 4 core virtuali sul mio computer (il che significa che dovrei essere in grado di avere solo 4 thread). Il conteggio dei thread indica tutti i thread gestiti dalle CPU quando decidono quale thread eseguire?

EDIT: Il motivo per cui penso che ci possano essere solo 4 thread sulla mia macchina deriva da questa risposta . Credo che il mio malinteso derivi dalla parola "filo" usata in un contesto diverso.


I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
bmike

Risposte:


24

programmazione

I tuoi 1.805 thread non vengono eseguiti contemporaneamente . Si scambiano. Un core esegue un po 'del thread, quindi lo mette da parte per eseguire un po' di un altro thread. Gli altri core fanno lo stesso. Tondo e tondo, i thread vengono eseguiti un po 'alla volta, non tutti in una volta.

Una delle maggiori responsabilità del sistema operativo (Darwin e macOS) è la pianificazione di quale thread deve essere eseguito su quale core per quanto tempo.

Molti thread non hanno lavoro da fare, quindi rimangono inattivi e non programmati. Allo stesso modo, molti thread potrebbero essere in attesa di alcune risorse come i dati da recuperare dalla memoria, o il completamento di una connessione di rete o il caricamento dei dati da un database. Con quasi nulla da fare se non controllare lo stato della risorsa attesa, tali thread sono programmati abbastanza brevemente, se non del tutto.

Il programmatore dell'app può aiutare questa operazione di pianificazione sospendendo il thread per un certo periodo di tempo quando sa che l'attesa per la risorsa esterna richiederà del tempo. E se esegue un ciclo "stretto" che richiede molta CPU senza motivo di attendere risorse esterne, il programmatore può inserire una chiamata al volontario per essere messo da parte brevemente in modo da non ingannare il core e quindi consentire l'esecuzione di altri thread.

Per maggiori dettagli, consultare la pagina Wikipedia per il multithreading .

Multi-threading simultaneo

Per quanto riguarda la tua domanda collegata , le discussioni sono effettivamente le stesse di qui.

Un problema è rappresentato dalle spese generali di passaggio tra thread quando pianificato dal sistema operativo. C'è un costo significativo nel tempo per scaricare le istruzioni e i dati del thread corrente dal core e quindi caricare le istruzioni e i dati del thread successivo pianificato. Parte del lavoro del sistema operativo è quello di cercare di essere intelligente nella pianificazione dei thread in modo da ottimizzare questo costo generale.

Alcuni produttori di CPU hanno sviluppato una tecnologia per ridurre questo tempo in modo da rendere la commutazione tra una coppia di thread molto più veloce. Intel chiama la loro tecnologia Hyper-Threading . Nota genericamente come multi-threading simultaneo (SMT) .

Mentre la coppia di thread non viene eseguita simultaneamente, la commutazione è così fluida e veloce che entrambi i thread sembrano essere praticamente simultanei. Funziona così bene che ogni core si presenta come una coppia di core virtuali al sistema operativo. Quindi una CPU abilitata per SMT con quattro core fisici, ad esempio, si presenterà al sistema operativo come una CPU a otto core.

Nonostante questa ottimizzazione, c'è ancora un certo sovraccarico nel passaggio tra tali core virtuali. Troppi thread ad alta intensità di CPU che chiedono a gran voce il tempo di esecuzione da programmare su un core possono rendere il sistema inefficiente, senza che nessuno esegua molto lavoro. Come tre palline in un parco giochi che vengono condivise tra nove bambini, rispetto alla condivisione tra novecento bambini in cui nessuno gioca davvero un serio gioco con una palla.

Quindi c'è un'opzione nel firmware della CPU in cui un amministratore di sistema può attivare un interruttore sulla macchina per disabilitare SMT se decide che sarebbe utile per i suoi utenti eseguire un'app che è insolitamente legata alla CPU con pochissime opportunità di pausa.

In tal caso, torniamo alla tua domanda originale: in questa situazione speciale vorrai davvero limitare le operazioni a non avere più di questi thread iperattivi di quanti ne hai i core fisici. Ma lasciatemi ripetere: questa è una situazione estremamente insolita che potrebbe verificarsi in qualcosa di simile a un progetto specializzato di analisi scientifica dei dati, ma non si applicherebbe quasi mai a scenari comuni di business / corporate / enterprise.


I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
bmike

Inoltre, nessuno inserisce yield()chiamate di sistema nei thread ad uso intensivo di CPU (a meno che non sia un codice legacy del multi-tasking cooperativo su MacOS classico). La riprogrammazione multi-tasking preventiva dopo che un thread ha esaurito il suo timeslice.
Peter Cordes,

La tua descrizione dell'hyperthreading è errata. Thread hardware! = Thread software, sono contesti di esecuzione / core logici. Entrambi i core logici su un core fisico eseguono davvero le loro istruzioni contemporaneamente. Il front-end si alterna tra i thread (ogni ciclo), ma il core di esecuzione fuori servizio può eseguire istruzioni / uops da entrambi i thread nello stesso ciclo. Questo espone il parallelismo a livello di istruzione da due thread all'esecuzione di OoO per mantenere meglio le unità di esecuzione alimentate con il lavoro (questo è fondamentalmente il punto di SMT). Non è solo "cambio di contesto ottimizzato".
Peter Cordes,


7

Ai vecchi tempi - la memoria non era virtualizzata o protetta e qualsiasi codice poteva scrivere ovunque. A quei tempi aveva un senso un design da thread a one CPU. Nei decenni successivi, la memoria fu prima protetta e poi virtualizzata. Pensa ai thread come core virtuali - una specie di promessa che a un certo momento, quando i tuoi dati e il tuo codice erano pronti, quel thread viene spinto ( o pianificato come gli ingegneri PHD e i matematici che fanno ricerche sugli algoritmi di pianificazione lo chiamano ) su una CPU reale per fare un vero lavoro.

inserisci qui la descrizione dell'immagine

Ora, a causa dell'enorme differenza nei tempi, la CPU e la cache funzionano così velocemente rispetto all'ottenimento di dati dalla memoria o dalla rete, che migliaia di thread potrebbero andare e venire mentre un thread è in attesa che www.google.com consegni un pacchetto o due di dati, ecco perché vedi tanti thread in più rispetto alla CPU reale.

Se converti le operazioni di thread che avvengono sulla scala temporale nero / blu e le converti in un secondo = 1 ns, le cose a cui teniamo sono più simili a quelle del disco IO che prendono 100 microsecondi sono come 4 giorni e un round trip di 200 ms è un Ritardo di 20 anni se si contano i secondi sulla scala temporale della CPU. Come molti poteri di dieci esercizi , in quasi tutti i casi - la CPU rimane inattiva per "mesi" in attesa di un lavoro significativo da un mondo esterno molto, molto lento.

Nulla sembra andare storto nell'immagine che hai pubblicato, quindi forse stiamo fraintendendo quello che stai ottenendo chiedendoti delle discussioni.

Se fai clic con il pulsante destro del mouse (control control) sui thread di parole nella riga di intestazione in alto, aggiungi lo stato dell'app e vedrai che la maggior parte dei thread sono probabilmente inattivi, inattivi, non in esecuzione in un dato momento.


I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
bmike

1

Non si pone la domanda discutibilmente più fondamentale, "Come posso avere 290 processi quando la mia CPU ha solo quattro core?" Questa risposta è un po 'di storia, che potrebbe aiutarti a capire il quadro generale, anche se alla domanda specifica è già stata data una risposta. Come tale, non ho intenzione di fornire una versione TL; DR.

C'era una volta (pensa, anni '50 -'60), i computer potevano fare solo una cosa alla volta. Erano molto costosi, riempivano intere stanze e avevamo bisogno di un modo per farne un uso efficiente condividendole tra più persone. Il primo modo per farlo era l'elaborazione in batch , in cui gli utenti avrebbero inviato attività al computer e sarebbero stati messi in coda, eseguiti uno dopo l'altro e i risultati sarebbero stati rispediti all'utente. Andava bene, ma significava che, se si voleva fare un calcolo che avrebbe richiesto un paio di giorni, nessun altro poteva usare il computer in quel periodo.

La prossima innovazione (credo, anni '60 -'70) fu la condivisione del tempo . Ora, invece di eseguire l'intero compito, quindi l'intero del prossimo, il computer eseguirà un po 'di un compito, quindi lo metterebbe in pausa ed eseguirà un po' del prossimo, e così via. Pertanto, il computer darebbe l'impressione di eseguire contemporaneamente più processi. Il grande vantaggio di questo è che ora puoi eseguire un calcolo che richiederà un paio di giorni e, anche se ora richiederà ancora più tempo, perché continua a essere interrotto, altre persone possono comunque usare la macchina durante quel periodo.

Tutto questo era per enormi computer in stile mainframe. Quando i personal computer hanno iniziato a diventare popolari, inizialmente non erano molto potenti e, ehi, dal momento che erano personali sembrava OK per loro poter fare solo una cosa - eseguire un'applicazione - alla volta (pensa, anni '80). Ma quando sono diventati più potenti (pensa, per presentare gli anni '90), anche le persone volevano che i loro personal computer condividessero il tempo.

Quindi abbiamo finito con i personal computer che davano l'illusione di eseguire più processi contemporaneamente eseguendoli uno alla volta per brevi periodi e poi sospendendoli. Le discussioni sono essenzialmente la stessa cosa: alla fine, le persone volevano persino i singoli processi per dare l'illusione di fare più cose contemporaneamente. Inizialmente, lo scrittore dell'applicazione doveva gestirlo da solo: passare un po 'di tempo ad aggiornare la grafica, mettere in pausa, passare un po' di tempo a calcolare, mettere in pausa, passare un po 'di tempo facendo qualcos'altro, ...

Tuttavia, il sistema operativo era già bravo a gestire più processi, aveva senso estenderlo per gestire questi sottoprocessi, che sono chiamati thread. Quindi, ora, abbiamo un modello in cui ogni processo (o applicazione) contiene almeno un thread, ma alcuni ne contengono diversi o molti. Ognuno di questi thread corrisponde a una sottoattività in qualche modo indipendente.

Ma, al livello più alto, la CPU continua a dare l'illusione che questi thread siano tutti in esecuzione contemporaneamente. In realtà, ne esegue uno per un po ', mettendolo in pausa, scegliendone un altro per correre un po' e così via. Solo che le moderne CPU possono eseguire più di un thread alla volta. Quindi, nella realtà reale , il sistema operativo sta giocando a questo gioco di "corri per un po ', metti in pausa, esegui qualcos'altro per un po', metti in pausa" su tutti i core contemporaneamente. Quindi, puoi avere quanti thread vuoi tu (e i tuoi progettisti di applicazioni) ma, in qualsiasi momento, tutti, tranne alcuni, verranno effettivamente messi in pausa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.