Laden...

Funktionen auf mehrere CPU Cores verteilen: Process oder Thread?

Erstellt von burli70 vor 7 Jahren Letzter Beitrag vor 7 Jahren 5.660 Views
B
burli70 Themenstarter:in
57 Beiträge seit 2016
vor 7 Jahren
Funktionen auf mehrere CPU Cores verteilen: Process oder Thread?

Hi, ich möchte verschiedene Funktionen auf mehrere CPU Cores verteilen, bin mir aber nicht sicher wo jetzt die Unterschiede zwischen Treads und Prozessen ist. Mit beidem kann man wohl Aufgaben auf mehrere Cores verteilen

Was ich gefunden habe ist, dass Prozesse isoliert voneinander laufen und Threads den gleichen Speicher teilen. Ist das so weit richtig? In den meisten Fällen wäre also Threads die bessere Wahl, wenn man auf die gleichen Daten zugreifen will.

Wann wären Prozesse sinnvoller? Nur wenn man externe Programme ausführen will?

W
955 Beiträge seit 2010
vor 7 Jahren

Hi,

Mache es anders rum und beschreibe mal was du vorhast. Es gibt z.B. das wichtige Konzept der Tasks und verschiedene Pattern dazu (z.B. Pipelining). Hängt davon ab was du machen willst.

16.835 Beiträge seit 2008
vor 7 Jahren

Die Relation ist folgende:

Prozesse (1) <---> (n) Threads (1) <---> (n) Tasks

Wie witte sagte, kommt es drauf an, was Du machen willst.
Normalerweise sollte man in .NET nur noch mit Tasks arbeiten, da sich diese viel einfacher und stabiler verwalten lassen.
Es gibt aber Szenarien, bei denen weiterhin Threads (aber mit Sorgfalt) verwendet wird. Geht es um eine Isolation würden auch Prozesse infrage kommen, was aber sehr selten ist und relativ viel Verwaltungsaufwand fordert.

Wenn man Multi-Threading in Angriff nehmen will, dann muss man die Basics fest im Griff haben.
Ansonsten ratterts schnell.
[Artikel] Multi-Threaded Programmierung

Ich geh jetzt aber so weit und behaupte, dass sich mehr als 90% aller Multi-Core-Aufgaben des normalen Entwicklers locker mit Tasks und entsprechenden Pattern abdecken lassen.
Tasks sind jedoch Abstraktionen des .NET Frameworks.

B
burli70 Themenstarter:in
57 Beiträge seit 2016
vor 7 Jahren

Generell will ich mal die Unterschiede wissen. Aber so wie ich das sehe wird mit Process.Start mehr oder weniger ein unabhängiges externes Programm gestartet.

Hintergrund ist der, dass ich einen Server für ein Minecraft ähnliches Spiel programmieren möchte und ich spiele mit dem Gedanken, verschiedene Aufgaben nicht nur parallel auf einem Multicore System laufen lassen zu können sondern optional verteilt auf mehreren Rechnern. Problem dabei wäre nur, dass Performnce und Speicher auf einem normalen PC darunter leiden würden

16.835 Beiträge seit 2008
vor 7 Jahren

Dann les Dich mal bitte in die Grundlagen ein.

Ein Programm erzeugt immer ein Prozess. Ein Prozess läuft aber immer auf einer Maschine.
Ein Thread gehört immer einem Prozess und kann nicht so einfach von von Prozess A auf Prozess B geschoben werden.

Das, von was Du redest, ist eine horizontale Skalierung einer Anwendungsstruktur.
Hier arbeitet man i.d.R. mit Queue-Systemen. Aufgaben werden in ein solches Queue-System gepumpt.
Andere Anwendungen (zB. ein "Consumer Prozess auf Maschine XZ") wartet auf Elemente in dieser Queue.

Das ist nichts anderes als das von witte angesprochene Pipelining, nur eben nicht mit Tasks sondern mit eigenen Anwendungen.

Wir machen sowas in einem IoT-Projekt für Haushaltsgeräte:
diese pushen verschiedene Nachrichten und vom Gerät direkt in Queues und Topics (das sind zwei verschiedene Sachen). Die Haushaötsgeräte agieren hier als Producer (also Nachrichtenerzeuger).
Auf vielen Servern laufen nun Windows Services (die Consumer), die Nachrichten lesen und die Arbeit machen.

Es hat schon seinen Sinn, dass Dich witte auf diese Richtung geschickt hatte.

B
burli70 Themenstarter:in
57 Beiträge seit 2016
vor 7 Jahren

Ein Programm erzeugt immer ein Prozess. Ein Prozess läuft aber immer auf einer Maschine.
Ein Thread gehört immer einem Prozess und kann nicht so einfach von von Prozess A auf Prozess B geschoben werden.

So hab ich das schon verstanden. Aber ein Prozess kann ja trotzdem einen anderen starten. Wenn das Spiel auf einem Rechner läuft kann der Hauptprozess die anderen ja automatisch starten, auf getrennten Rechnern muss man das eben manuell machen.

Die Kommunikation zwischen den Prozessen muss dann aber über ein Netzwerkprotokoll oder ähnliches erfolgen und jeder Prozess muss seine eigenen Daten vorhalten. Wenn man das alles in Threads macht können alle Threads auf die gleichen Daten zugreifen

Ich lese mich da weiter ein. Es ging mir hier nur erst mal um ein grundlegendes Verständnis

16.835 Beiträge seit 2008
vor 7 Jahren

Es kommt halt drauf an, was Du machen willst.
Professionelle "Node-Strukturen" gibts zB. Frameworks wie Akka.NET, wobei jeder Server dann ein Akka-Service bekommt, und der je nach Aufgaben dann zB. Prozesse startet.
Der Aufwand der Verwaltung ist aber nicht unerheblich. Was eigenes basteln... kostet Zeit 😉

B
burli70 Themenstarter:in
57 Beiträge seit 2016
vor 7 Jahren

Unter dem Strich habe ich zwei Situationen. Zum einen will ich beim Programmstart verschiedene Threads starten, die verschiedene Aufgaben übernehmen, aber unter Umständen auf die gleichen Daten zugreifen

Zum anderen habe ich kurzzeitig parallele Threads, um irgend eine Datenverarbeitung zu erledigen

Jetzt bin ich irritiert. In diesem Video heiß es, dass Threads nur auf einem Single Core laufen, Tasks "are multi-core aware"

Woanders hab ich gelesen, Threads "können" auf einem anderen Core laufen, müssen aber nicht.

Demnach wären Threads nicht das richtige für meine Anwendung, oder?

16.835 Beiträge seit 2008
vor 7 Jahren

Prozesse und Threads sind Teil von Windows, das auch über das Windows Process bzw. Windows Thread Scheduling verwaltet wird.
Ein Prozess ist vereinfacht gesagt nur eine Hülle; die eigentliche Aufgabe bzw. Ausführung erfolgt in einem Thread.

Tasks gibt es in dieser Form nur in .NET. Sie bilden eine zusätzliche Abstraktionsschicht, da Threads relativ umständlich zu handhaben und "teuer" sind.
Tasks machen es .NET Entwicklern einfacher, sicherer und günstiger, Multi-Threaded Anwendungen zu schreiben.

Jeder Thread kann immer nur auf einem Kern zeitgleich laufen.
Vereinfacht gesagt (ist dann aber doch komplexer): eine Anwendung, die nur einen Thread hat, kann zB. auf einem 4-Kern Prozessor maximal 25% der Leistung beanspruchen.
Der Thread kann eben nur auf einem Kern ausgeführt werden.

Daher machts natürlich sinn mehrere Threads zu verwenden, damit diese die vorhandene Leistung eines Rechners auch nutzen.
Das Windows Scheduling ist aber sehr komplex; Windows versucht dabei die Core-Auslastung gleichmäßig zu verteilen.

Threads zu erstellen ist aber sehr Ressourcen-intensiv. So wird zB. immer ein fester Speicher pro Thread reserviert. Auch hast Du auch nur eine begrenze Anzahl von Threads auf dem System zur Verfügung.
Daher gibt es eben die Threads. .NET hält sich hier immer eine Anzahl von Threads vor, sodass diese nicht ständig neu angelegt werden müssen, sondern .NET diese immer und immer wieder für verschiedene Tasks verwenden kann.
.NET hat hierfür einen eigenen Task Scheduler.

Jeder Task hat und braucht einen Thread, indem die Aufgaben ausgeführt werden. Ein Thread kann aber mehrere Tasks verwalten; ist einfach effizienter.

Ich such mal ein Schaubild, das ich hier mal im Forum zur Verfügung gestellt hab und verlinke es dann hier.
Edit: hier gefunden Task - Verständnisproblem - async - await - UI-Thread

B
burli70 Themenstarter:in
57 Beiträge seit 2016
vor 7 Jahren

In dem Video klingt es eher so, als würden auch mehrere Threads (innerhalb eines Prozess) nur auf einem Core ausgeführt, also nur quasi parallel

Ab etwa 3:05 heißt es zB

Threads are primarily used to simulate the idea of multiple things happening on a single processor

Ab etwa 5:03 heißt es:

So Threads basically run on a single core

Threads sind also eher dazu da, dass die GUI weiter läuft wenn das Programm im Hintergrund was macht. Ganz davon abgesehen das Threads, wie du schon erwähnt hast, Speicher und die Umschaltung zwischen ihnen Zeit kosten.

Es kann natürlich sein, dass das Betriebssystem einen neuen Thread in enen anderen Core legt, aber das scheint nicht garantiert zu sein.

16.835 Beiträge seit 2008
vor 7 Jahren

Du Schlussfolgerst aufgrund Vermutungen - und das wird nach Hinten los gehen.

Jeder Thread kann auf jedem Core laufen, ausser er wird mit Hilfe der ThreadAffinity auf einen spezifischen Core fixiert.
Das ist aber i.d.R. nicht der Fall.
Multiple Processors

Ein Single Processor heisst aber nicht ein Single Thread.
Ein Prozessor kann mehrere Kerne haben und zB. mit Hyper-Threading noch mehr Threads gleichzeitig ausführen.

Ein Dual Core -Prozessor kann dank Hyper-Threading 4 Threads gleichzeitig arbeiten lassen.
Ein Quad Core mit Hyper-Threading dann sogar 8 Threads.

Un ja, Threads laufen immer auf einem Kern.
Ein Thread kann nicht auf mehreren Kernen oder mehreren Hyper-Threads laufen. Hab ich ja oben schon gesagt.
Du musst noch die Unterschiede zwischen Prozessor, Core, Thread und Task verstehen 😉

Und nein, Threads sind nichts UI spezifisches. Sondern Threads ist für jegliche Nebenläufigkeit, wobei eben die Reaktionsfähigkeit der UI nur eine von vielen vielen Anwendungsfällen ist.

B
burli70 Themenstarter:in
57 Beiträge seit 2016
vor 7 Jahren

Ok. Also verwende ich für die meisten Sachen Tasks. Aber was verwende ich für die Funktionen, die über die gesamte Laufzeit aktiv sind?

Mein Game Server soll aus mehreren Teilen bestehen wie Netzwerk Server, Map Generator und noch 1-2 andere Sachen. Kann ich da auch Tasks verwenden? Wobei zB der Map Generator selbst für seine Arbeit Tasks benötigt, um die Arbeit auf mehrere Cores zu verteilen.

16.835 Beiträge seit 2008
vor 7 Jahren

Du hast wohl mehrere Szenarien.

Du willst zum einen mehrere Anwendungen, die jeweils ihren eigenen Prozess haben und wiederum pro Prozess mehrere Tasks, die die Aufgaben abarbeiten.

Mach am besten kleine Schritte beim Thema Multi Threaded und versuch nicht gleich ne riesen Landschaft abzudecken.

B
burli70 Themenstarter:in
57 Beiträge seit 2016
vor 7 Jahren

Mir ist klar, dass ich gleich in die Vollen springe. Ich versuche nur, mir einen Überblick zu verschaffen damit ich am Anfang nicht gleich völlig in die falsche Richtung laufe. Vorher werde ich aber für jeden Teil ein eigenes Projekt machen und damit experimentieren