Optimale Anzahl von Threads beim Multitasking

4

Ich weiß, dass ähnliche Fragen gestellt wurden, aber ich denke, mein Fall ist ein bisschen anders.

Angenommen, ich habe einen Computer mit 8 Kernen und unendlich viel Speicher mit einem Linux-Betriebssystem.

Ich habe eine Berechnungssoftware namens Gaussian, die Multithreading nutzen kann. Deshalb habe ich die Fadenzahl für eine einzelne Berechnung auf 8 gesetzt, um die maximale Geschwindigkeit zu erreichen. Ich kann mich jedoch wirklich nicht entscheiden, was ich tun soll, wenn ich beispielsweise 8 Berechnungen gleichzeitig ausführen muss. In diesem Fall sollte ich die Thread-Anzahl für jeden Job auf 1 setzen (insgesamt 8 Threads, die in 8 Prozessen erzeugt wurden) oder 8 behalten (insgesamt 64 Threads, die in 8 Prozessen erzeugt wurden)? Macht es wirklich viel aus? Eine verwandte Frage ist, ob das Betriebssystem das Core-Parking automatisch für jeden Thread auf verschiedene Cores anwendet.

EDIT: Ich weiß, das Benchmarking ist der beste Weg zu wissen. Die Computer gehören meiner Universität und sind die ganze Zeit beschäftigt. Mit anderen Worten, seine Arbeitsbelastung ist für mich unkontrollierbar unterschiedlich, weil andere Leute diese Computer auch für ihre Berechnungen verwenden, was das Experimentieren unmöglich macht. Auch die Software ist sehr teuer (1500 $ oder so) und für jeden Computer lizenziert, so dass ich nicht einfach einen Benchmark auf meinem PC ausführen kann ...

theGD
quelle
Unter Berücksichtigung der gegebenen (richtigen und genauen) Antworten gibt es keine Garantie dafür, dass das Programm mit einer maximalen Anzahl von Threads besser funktioniert als mit einem einzelnen Thread (dh es ist möglicherweise besser für einen einzelnen Thread programmiert, einige Threads verlangsamen möglicherweise den Prozess) insgesamt etc), obwohl wenn es programmiert ist, sollte es . Wie der allgemeine Konsens zeigt, ist es am besten, jede Konfiguration mit einem begrenzten Test-Set zu vergleichen.
Doktoro Reichard
Sie sollten es einfach messen.
Der Hochstapler

Antworten:

5

Im Idealfall sollte die Gesamtanzahl der Threads für alle Jobs der Anzahl der Kerne des Systems entsprechen, mit Ausnahme von Systemen, die Hyper-Threading unterstützen. In diesen Systemen sollte die doppelte Anzahl der Kerne angegeben werden. Wenn das System über kein Hyper-Threading verfügt, werden 8 Berechnungen ausgeführt, von denen jede in einem Thread ausgeführt werden sollte.

Viele Intel-Prozessoren sind mit Hyper-Threading ausgestattet, sodass jeder Kern zwei Threads unterstützen kann. Zum Beispiel sollte ein 8-Kern-System, das Hyper-Threading unterstützt, 16 Threads haben, um das System voll auszunutzen.

Ramchandra Apte
quelle
3

Die Antwort hängt davon ab, was der Prozess macht und wie sein Multithreading programmiert wurde, was bedeutet, dass Sie experimentieren müssen.

Wenn der Prozess Semaphoren und andere Ausschlussmechanismen für Konflikte zwischen den Threads auf gemeinsamen Ressourcen (z. B. Speicher) verwendet, ist die Anzahl der wartenden Konflikte umso geringer, je weniger Threads im Prozess vorhanden sind.

Während einer Wartezeit unternimmt der Thread nichts, sodass sich Wartezeiten negativ auf den Durchsatz auswirken. In diesem Fall verbessern mehr Prozesse und weniger Threads pro Prozess den Durchsatz, sodass 8x8 eine bessere Leistung als 1x64 bietet.

Wenn jedoch jeder Thread vollständig isoliert ist und keine gemeinsamen Ressourcen vorhanden sind, plant das Betriebssystem die Threads, ohne zwischen den beiden Fällen 8x8 oder 1x64 zu unterscheiden. In diesem Fall ist nur die Gesamtzahl der Threads für den Gesamtdurchsatz von Bedeutung, sodass beide Fälle die gleiche Leistung erbringen.

Harrymc
quelle
Wenn Ihr Update besagt, dass die Computer sehr ausgelastet sind, haben zu viele Threads den gegenteiligen Effekt, dass der Computer verlangsamt wird. Das Wechseln der CPU zwischen Threads ist ein kostspieliger Vorgang.
Harrymc
3

Die richtige Anzahl hängt davon ab, wie viel Zeit die Prozesse für E / A blockiert haben.

Das Buch "Programming Concurrency on the JVM" enthält einige gute Informationen dazu:

"Ermitteln der Anzahl der Threads". Für ein großes Problem möchten wir mindestens so viele Threads haben, wie Kerne zur Verfügung stehen. Dies stellt sicher, dass so viele Kerne wie möglich für die Lösung unseres Problems eingesetzt werden ...

Die Mindestanzahl der Threads entspricht also der Anzahl der verfügbaren Kerne. Wenn alle Aufgaben rechenintensiv sind, ist dies alles, was wir brauchen. In diesem Fall schadet es tatsächlich, wenn mehr Threads vorhanden sind, da Kerne den Kontext zwischen Threads wechseln, wenn noch Arbeit zu erledigen ist. Wenn Aufgaben IO-intensiv sind, sollten wir mehr Threads haben.

Wenn eine Task eine E / A-Operation ausführt, wird ihr Thread blockiert. Der Prozessorkontext wechselt sofort, um andere auswählbare Threads auszuführen. Wenn wir nur so viele Threads hatten, wie Kerne zur Verfügung stehen, können sie nicht ausgeführt werden, obwohl Aufgaben zu erledigen sind, da sie nicht für Threads geplant wurden, die von den Prozessoren abgerufen werden sollen.

Wenn Aufgaben 50 Prozent der Zeit blockiert werden, sollte die Anzahl der Threads doppelt so hoch sein wie die Anzahl der verfügbaren Kerne. Wenn sie weniger Zeit damit verbringen, blockiert zu werden - das heißt, sie sind rechenintensiv -, sollten wir weniger Threads haben, aber nicht weniger als die Anzahl der Kerne. Wenn sie mehr Zeit damit verbringen, blockiert zu werden - das heißt, sie sind IO-intensiv -, sollten wir mehr Threads haben, insbesondere mehrere Vielfache der Anzahl der Kerne.

So können wir die Gesamtzahl der benötigten Threads wie folgt berechnen:

Anzahl der Threads = Anzahl der verfügbaren Kerne / (1 - Blocking Coefficient)

Wenn Sie mehrere Berechnungen gleichzeitig ausführen müssen, prüfen Sie möglicherweise, ob es möglich ist, sie innerhalb eines Prozesses mit einem Thread-Pool auszuführen, dessen Größe angemessen ist.

Andernfalls haben Sie möglicherweise zu viele Threads, wenn Sie die optimale Anzahl von Threads für eine Berechnung haben, aber dann 8 gleichzeitig ausführen.

Die beste Lösung ist ein experimentelles Benchmarking.

Ich bin mir nicht ganz sicher, was Sie unter Core-Parken verstehen, aber die CPU wird aus Cache-Gründen tendenziell denselben Thread auf einem bestimmten Core ausführen, obwohl sie ihn manchmal auch aus verschiedenen Wärme- / Stromgründen verschiebt. Sie können dies mit einem Tool wie htop untersuchen.

stephenbez
quelle
Die Sache ist, dass die Computer zu meiner Universität gehören und die ganze Zeit beschäftigt sind. Mit anderen Worten, die Arbeitslast ist für mich unkontrollierbar unterschiedlich, da andere Leute diese PCs auch für ihre Berechnungen verwenden, was das Experimentieren unmöglich macht.
theGD
E / A ist keineswegs die einzige gemeinsam genutzte Ressource zwischen Threads.
Harrymc
1

Sie haben die Frage selbst beantwortet. "Die Computer gehören zu meiner Universität und sind die ganze Zeit beschäftigt."

Man bekommt eigentlich nur einen Teil der Prozessoren. Um die Arbeit so effizient wie möglich zu erledigen, sollten Sie den Aufwand für das Schalten von Aufgaben und das Multiplexen sowie das Warten auf Ressourcen auf ein Minimum beschränken.

Multithreading ist immer weniger effizient, wenn es auf der Grundlage der "Verarbeitungsleistung" berechnet wird, da der Overhead für die Kontextumschaltung auftritt. Dies beschleunigt nur die Probleme bei der Nutzung aller "freien" nicht belegten Ressourcen. Idee: Verwenden Sie 8 Computer, um ein Problem in wahrscheinlich 7,9-mal schneller auszuführen, das niemals über 8 liegen kann.

Wenn all dies für Sie bestimmt ist, tun Sie es einfach parallel, um die Geschwindigkeit zu erhöhen. Andernfalls behalten Sie einen Thread bei und lassen Sie andere den verbleibenden Kern für andere Arbeiten verwenden.

Übrigens gibt es auf egoistische Art und Weise ein Red Hat-Tool, das Grid aufruft und Sie auf alle Linux-Benutzer über den Campus verteilt. (> 200). Es wird so schnell laufen, nur nicht erwischt werden, da es alle verlangsamen wird. oder benutze die alten tools, mathlab parallel.


quelle