Wie kann ich 1805 Threads haben, wenn ich nur 4 virtuelle CPUs habe?

10

Ich habe mich gefragt, ob mir jemand erklären könnte, wie in meinem Aktivitätsmonitor angegeben ist, dass ich derzeit 1805 Threads habe Screenshot von OS X Activity Monitor

Aber ich habe nur 4 virtuelle Kerne auf meinem Computer (was bedeutet, dass ich nur 4 Threads haben sollte). Bedeutet die Thread-Anzahl alle Threads, die von den CPUs verarbeitet werden, wenn sie entscheiden, welcher Thread ausgeführt werden soll?

EDIT: Der Grund, warum ich denke, dass es nur 4 Threads auf meinem Computer geben kann, kommt von dieser Antwort . Ich glaube, dass mein Missverständnis darauf zurückzuführen ist, dass das Wort "Thread" in einem anderen Kontext verwendet wird.

YellowPillow
quelle
Kommentare sind nicht für eine ausführliche Diskussion gedacht. Dieses Gespräch wurde in den Chat verschoben .
bmike

Antworten:

24

Planung

Ihre 1.805 Threads werden nicht gleichzeitig ausgeführt . Sie tauschen sich aus. Ein Kern führt ein Stück des Threads aus und legt es dann beiseite, um ein Stück eines anderen Threads auszuführen. Die anderen Kerne machen dasselbe. Rund und rund, Threads werden ein wenig nach dem anderen ausgeführt, nicht alle auf einmal.

Eine Hauptverantwortung des Betriebssystems (Darwin und macOS) ist die Planung, welcher Thread wie lange auf welchem ​​Kern ausgeführt werden soll.

Viele Threads haben keine Arbeit zu erledigen und bleiben daher ruhend und außerplanmäßig. Ebenso warten möglicherweise viele Threads auf eine Ressource, z. B. Daten, die aus dem Speicher abgerufen werden sollen, oder eine Netzwerkverbindung, die abgeschlossen werden soll, oder Daten, die aus einer Datenbank geladen werden sollen. Da fast nichts anderes zu tun ist, als den Status der erwarteten Ressource zu überprüfen, werden solche Threads, wenn überhaupt, recht kurz geplant.

Die App-Programmiererin kann diesen Planungsvorgang unterstützen, indem sie ihren Thread für eine bestimmte Zeit in den Ruhezustand versetzt, wenn sie weiß, dass das Warten auf die externe Ressource einige Zeit dauern wird. Und wenn eine „enge“ Schleife ausgeführt wird, die CPU-intensiv ist und keinen Grund hat, auf externe Ressourcen zu warten, kann der Programmierer einen Aufruf an die Freiwillige einfügen, der kurz beiseite gelegt werden soll, um den Kern nicht zu belasten und dadurch die Ausführung anderer Threads zu ermöglichen.

Weitere Informationen finden Sie auf der Wikipedia-Seite für Multithreading .

Gleichzeitiges Multithreading

Was Ihre verknüpfte Frage betrifft, so sind die Threads dort tatsächlich dieselben wie hier.

Ein Problem sind die Overhead-Kosten für das Wechseln zwischen Threads, wenn dies vom Betriebssystem geplant wird. Das Entladen der Anweisungen und Daten des aktuellen Threads aus dem Kern und das anschließende Laden der Anweisungen und Daten des nächsten geplanten Threads ist mit erheblichen Zeitkosten verbunden. Ein Teil der Aufgabe des Betriebssystems besteht darin, bei der Planung der Threads klug zu sein, um diese Gemeinkosten zu optimieren.

Einige CPU-Hersteller haben Technologien entwickelt, um diese Zeit zu verkürzen und den Wechsel zwischen zwei Threads zu beschleunigen. Intel nennt ihre Technologie Hyper-Threading . Allgemein bekannt als simultanes Multithreading (SMT) .

Während das Thread-Paar nicht gleichzeitig ausgeführt wird, ist das Umschalten so reibungslos und schnell, dass beide Threads praktisch gleichzeitig zu sein scheinen. Dies funktioniert so gut, dass sich jeder Kern dem Betriebssystem als ein Paar virtueller Kerne präsentiert. So präsentiert sich beispielsweise eine SMT-fähige CPU mit vier physischen Kernen dem Betriebssystem als Acht-Kern-CPU.

Trotz dieser Optimierung ist das Umschalten zwischen solchen virtuellen Kernen immer noch mit einem gewissen Aufwand verbunden. Zu viele CPU-intensive Threads, die alle nach einer auf einem Kern geplanten Ausführungszeit verlangen, können das System ineffizient machen, ohne dass ein Thread viel Arbeit erledigt. Wie drei Bälle auf einem Spielplatz, die von neun Kindern geteilt werden, im Vergleich zu neunhundert Kindern, bei denen kein Kind wirklich ernsthaft mit einem Ball spielt.

Daher gibt es in der CPU-Firmware eine Option, mit der ein Systemadministrator einen Schalter auf dem Computer betätigen kann, um SMT zu deaktivieren, wenn er entscheidet, dass dies seinen Benutzern zugute kommt, die eine App ausführen, die ungewöhnlich CPU-gebunden ist und nur sehr wenige Möglichkeiten zum Anhalten bietet.

In einem solchen Fall kehren wir zu Ihrer ursprünglichen Frage zurück: In dieser speziellen Situation möchten Sie die Operationen tatsächlich so einschränken, dass nicht mehr dieser hyperaktiven Threads als physische Kerne vorhanden sind. Aber lassen Sie mich wiederholen: Dies ist eine äußerst ungewöhnliche Situation, die in so etwas wie einem speziellen wissenschaftlichen Datenverarbeitungsprojekt auftreten kann, aber fast nie für gängige Geschäfts- / Unternehmens- / Unternehmensszenarien gelten würde.

Basil Bourque
quelle
Kommentare sind nicht für eine ausführliche Diskussion gedacht. Dieses Gespräch wurde in den Chat verschoben .
bmike
Außerdem fügt niemand yield()Systemaufrufe in seine CPU-intensiven Threads ein (es sei denn, es handelt sich um Legacy-Code aus kooperativem Multitasking unter Classic MacOS). Präventive Multitasking-Neupläne, nachdem ein Thread seine Zeitscheibe aufgebraucht hat.
Peter Cordes
Ihre Beschreibung von Hyperthreading ist falsch. Hardware-Threads! = Software-Threads, sie sind Ausführungskontexte / logische Kerne. Beide logischen Kerne auf einem physischen Kern führen ihre Anweisungen tatsächlich gleichzeitig aus. Das Front-End wechselt zwischen Threads (jeder Zyklus), aber der Ausführungskern außerhalb der Reihenfolge kann Anweisungen / Uops von beiden Threads im selben Zyklus ausführen. Dies macht die Parallelität auf Befehlsebene von zwei Threads zur OoO-Ausführung verfügbar, um die Ausführungseinheiten besser mit Arbeit zu versorgen (dies ist im Grunde der Punkt von SMT). Es ist nicht nur "optimierte Kontextumschaltung".
Peter Cordes
en.wikipedia.org/wiki/Hyper-threading hat ein Diagramm. Siehe auch die generische en.wikipedia.org/wiki/Simultaneous_multithreading
Peter Cordes
7

Früher war der Speicher weder virtualisiert noch geschützt, und jeder Code konnte überall schreiben. In jenen Tagen war ein Design von einem Thread zu einer CPU sinnvoll. In den Jahrzehnten seitdem wurde der Speicher zuerst geschützt und dann virtualisiert. Stellen Sie sich Threads als virtuelle Kerne vor - eine Art Versprechen, dass zu einem Zeitpunkt, an dem Ihre Daten und Ihr Code fertig waren, dieser Thread auf eine tatsächliche CPU übertragen wird ( oder geplant wird, wie es die PHD-Ingenieure und Mathematiker, die nach Planungsalgorithmen forschen, nennen ) mache die eigentliche Arbeit.

Geben Sie hier die Bildbeschreibung ein

Aufgrund der unterschiedlichen Timing-Werte arbeiten CPU und Cache im Vergleich zum Abrufen von Daten aus dem Speicher oder dem Netzwerk so schnell, dass Tausende von Threads kommen und gehen können, während ein Thread darauf wartet, dass www.google.com eine liefert Ein oder zwei Datenpakete, deshalb sehen Sie so viel mehr Threads als die tatsächliche CPU.

Wenn Sie die Thread-Operationen, die auf der Schwarz / Blau-Zeitskala ausgeführt werden, konvertieren und in eine Sekunde = 1 ns konvertieren, sind die Dinge, die uns wichtig sind, eher wie Festplatten-E / A, die 100 Mikrosekunden dauern, wie 4 Tage und eine 200-ms-Internet-Roundtrip ist eine 20 Jahre Verzögerung, wenn Sie Sekunden auf der CPU-Zeitskala zählen. Wie bei vielen Zehnerpotenzen sitzt die CPU in fast allen Fällen "Monate" im Leerlauf und wartet auf sinnvolle Arbeit aus einer sehr, sehr langsamen Außenwelt.

In dem von Ihnen geposteten Bild scheint nichts falsch zu sein. Vielleicht verstehen wir falsch, worauf Sie sich einlassen, wenn wir uns über Themen wundern.

Wenn Sie mit der rechten Maustaste (Steuerklick) auf die Wort-Threads in der Kopfzeile oben klicken, fügen Sie den Status der App hinzu, und Sie werden sehen, dass die meisten Threads wahrscheinlich inaktiv sind, schlafen und zu einem bestimmten Zeitpunkt nicht ausgeführt werden.

bmike
quelle
Kommentare sind nicht für eine ausführliche Diskussion gedacht. Dieses Gespräch wurde in den Chat verschoben .
bmike
1

Sie stellen nicht die wohl grundlegendere Frage: "Wie kann ich 290 Prozesse haben, wenn meine CPU nur vier Kerne hat?" Diese Antwort ist ein Stück Geschichte, das Ihnen helfen könnte, das Gesamtbild zu verstehen, obwohl die spezifische Frage bereits beantwortet wurde. Daher werde ich keine TL; DR-Version geben.

Es war einmal (denken Sie an die 1950er bis 1960er Jahre), als Computer immer nur eine Sache gleichzeitig tun konnten. Sie waren sehr teuer, füllten ganze Räume, und wir brauchten eine Möglichkeit, sie effizient zu nutzen, indem wir sie zwischen mehreren Personen teilten. Die erste Möglichkeit hierfür war die Stapelverarbeitung , bei der Benutzer Aufgaben an den Computer senden und in die Warteschlange gestellt, nacheinander ausgeführt und die Ergebnisse an den Benutzer zurückgesendet werden. Das war in Ordnung, aber es bedeutete, dass während dieser Zeit niemand den Computer benutzen konnte, wenn Sie eine Berechnung durchführen wollten, die einige Tage dauern würde.

Die nächste Neuerung (denken Sie an die 1960er bis 1970er Jahre) war das Teilen von Zeit . Anstatt nun die gesamte Aufgabe und dann die gesamte nächste Aufgabe auszuführen, führt der Computer ein Stück einer Aufgabe aus, hält sie dann an und führt ein Stück der nächsten aus, und so weiter. Somit würde der Computer den Eindruck erwecken, dass er mehrere Prozesse gleichzeitig ausführt. Der große Vorteil davon ist, dass Sie jetzt eine Berechnung ausführen können, die einige Tage dauert, und obwohl sie jetzt noch länger dauert, weil sie immer wieder unterbrochen wird, können andere Personen die Maschine während dieser Zeit weiterhin verwenden.

All dies war für riesige Computer im Mainframe-Stil gedacht. Als PCs immer beliebter wurden, waren sie anfangs nicht sehr leistungsfähig, und da sie persönlich waren , schien es für sie in Ordnung, nur eine Sache gleichzeitig ausführen zu können (denken Sie an die 1980er Jahre). Aber als sie leistungsfähiger wurden (denken Sie an die 90er Jahre bis heute), wollten die Leute, dass ihre PCs auch die Zeit teilen.

So kamen wir zu PCs, die die Illusion erweckten, mehrere Prozesse gleichzeitig auszuführen, indem sie für kurze Zeit einzeln ausgeführt und dann angehalten wurden. Themen sind im Wesentlichen dasselbe: Schließlich wollten die Menschen sogar einzelne Prozesse, um die Illusion zu erzeugen, mehrere Dinge gleichzeitig zu tun. Zuerst musste der Anwendungsschreiber selbst damit umgehen: ein wenig Zeit damit verbringen, die Grafiken zu aktualisieren, das anzuhalten, ein wenig Zeit damit zu verbringen, zu rechnen, das anzuhalten, etwas Zeit damit zu verbringen, etwas anderes zu tun, ...

Das Betriebssystem war jedoch bereits gut darin, mehrere Prozesse zu verwalten. Es war sinnvoll, es auf die Verwaltung dieser Unterprozesse zu erweitern, die als Threads bezeichnet werden. Jetzt haben wir also ein Modell, bei dem jeder Prozess (oder jede Anwendung) mindestens einen Thread enthält, einige jedoch mehrere oder viele. Jeder dieser Threads entspricht einer etwas unabhängigen Unteraufgabe.

Auf der obersten Ebene gibt die CPU jedoch immer noch nur die Illusion, dass diese Threads alle gleichzeitig ausgeführt werden. In Wirklichkeit läuft es ein bisschen, hält es an, wählt ein anderes aus, um ein bisschen zu laufen, und so weiter. Außer dass moderne CPUs mehr als einen Thread gleichzeitig ausführen können. Also, in der realen Wirklichkeit, das Betriebssystem spielt dieses Spiel „laufen für ein bisschen, Pause, laufen etwas anderes für ein bisschen, Pause“ auf alle Kerne gleichzeitig. Sie können also so viele Threads haben, wie Sie (und Ihre Anwendungsdesigner) möchten, aber zu jedem Zeitpunkt werden alle bis auf einige tatsächlich angehalten.

David Richerby
quelle