Angenommen, ich habe eine 4-Kern-CPU und möchte einen Prozess in kürzester Zeit ausführen. Der Prozess ist idealerweise parallelisierbar, sodass ich Teile davon auf einer unendlichen Anzahl von Threads ausführen kann und jeder Thread die gleiche Zeit benötigt.
Da ich 4 Kerne habe, erwarte ich keine Beschleunigung, indem mehr Threads als Kerne ausgeführt werden, da ein einzelner Kern nur zu einem bestimmten Zeitpunkt einen einzelnen Thread ausführen kann. Ich weiß nicht viel über Hardware, daher ist dies nur eine Vermutung.
Gibt es einen Vorteil, wenn ein parallelisierbarer Prozess auf mehr Threads als Kernen ausgeführt wird? Mit anderen Worten, wird mein Prozess schneller, langsamer oder in ungefähr der gleichen Zeit abgeschlossen, wenn ich ihn mit 4000 Threads anstatt mit 4 Threads ausführe?
quelle
Ich stimme der Antwort von @ Gonzalo zu. Ich habe einen Prozess, der keine E / A ausführt, und hier ist, was ich gefunden habe:
Beachten Sie, dass alle Threads in einem Array arbeiten, jedoch in unterschiedlichen Bereichen (zwei Threads greifen nicht auf denselben Index zu). Daher können die Ergebnisse unterschiedlich sein, wenn sie in unterschiedlichen Arrays gearbeitet haben.
Die 1.86-Maschine ist ein MacBook Air mit einer SSD. Der andere Mac ist ein iMac mit einer normalen Festplatte (ich denke, es ist 7200 U / min). Die Windows-Maschine hat auch eine Festplatte mit 7200 U / min.
In diesem Test war die optimale Anzahl gleich der Anzahl der Kerne in der Maschine.
quelle
Ich weiß, dass diese Frage ziemlich alt ist, aber die Dinge haben sich seit 2009 weiterentwickelt.
Es sind jetzt zwei Dinge zu berücksichtigen: die Anzahl der Kerne und die Anzahl der Threads, die in jedem Kern ausgeführt werden können.
Bei Intel-Prozessoren wird die Anzahl der Threads durch das Hyperthreading definiert, das nur 2 beträgt (sofern verfügbar). Aber Hyperthreading verkürzt Ihre Ausführungszeit um zwei, selbst wenn Sie nicht zwei Threads verwenden! (dh 1 Pipeline, die von zwei Prozessen gemeinsam genutzt wird - dies ist gut, wenn Sie mehr Prozesse haben, sonst nicht so gut. Mehr Kerne sind definitiv besser!)
Auf anderen Prozessoren haben Sie möglicherweise 2, 4 oder sogar 8 Threads. Wenn Sie also 8 Kerne haben, von denen jeder 8 Threads unterstützt, können 64 Prozesse ohne Kontextwechsel parallel ausgeführt werden.
"Keine Kontextumschaltung" ist offensichtlich nicht der Fall, wenn Sie mit einem Standardbetriebssystem arbeiten, das die Kontextumschaltung für alle möglichen anderen Dinge außerhalb Ihrer Kontrolle ausführt. Aber das ist die Hauptidee. Bei einigen Betriebssystemen können Sie Prozessoren zuweisen, sodass nur Ihre Anwendung Zugriff auf diesen Prozessor hat.
Nach meiner eigenen Erfahrung sind mehrere Threads gut, wenn Sie viele E / A haben. Wenn Sie sehr viel speicherintensive Arbeit haben (Quelle 1 lesen, Quelle 2 lesen, schnelle Berechnung, Schreiben), hilft es nicht, mehr Threads zu haben. Dies hängt wiederum davon ab, wie viele Daten Sie gleichzeitig lesen / schreiben (dh wenn Sie SSE 4.2 verwenden und 256-Bit-Werte lesen, werden alle Threads in ihrem Schritt gestoppt ... mit anderen Worten, 1 Thread ist wahrscheinlich viel einfacher zu implementieren und Wahrscheinlich fast genauso schnell, wenn nicht sogar schneller. Dies hängt von Ihrer Prozess- und Speicherarchitektur ab. Einige erweiterte Server verwalten separate Speicherbereiche für separate Kerne, sodass separate Threads schneller sind, vorausgesetzt, Ihre Daten werden ordnungsgemäß abgelegt Architekturen, 4 Prozesse laufen schneller als 1 Prozess mit 4 Threads.)
quelle
Die tatsächliche Leistung hängt davon ab, wie viel freiwilliges Nachgeben jedes Threads bewirkt. Wenn die Threads beispielsweise überhaupt KEINE E / A ausführen und keine Systemdienste verwenden (dh sie sind zu 100% an die CPU gebunden), ist 1 Thread pro Kern optimal. Wenn die Threads etwas tun, das ein Warten erfordert, müssen Sie experimentieren, um die optimale Anzahl von Threads zu ermitteln. 4000 Threads würden einen erheblichen Planungsaufwand verursachen, daher ist dies wahrscheinlich auch nicht optimal.
quelle
Die Antwort hängt von der Komplexität der im Programm verwendeten Algorithmen ab. Ich habe eine Methode entwickelt, um die optimale Anzahl von Threads zu berechnen, indem zwei Messungen der Verarbeitungszeiten Tn und Tm für zwei beliebige Anzahl von Threads 'n' und 'm' durchgeführt wurden. Für lineare Algorithmen ist die optimale Anzahl von Threads N = sqrt ((m n (Tm * (n-1) - Tn * (m-1))) / (n Tn-m Tm)).
Bitte lesen Sie meinen Artikel über die Berechnung der optimalen Anzahl für verschiedene Algorithmen: pavelkazenin.wordpress.com
quelle
Ich dachte, ich würde hier eine andere Perspektive hinzufügen. Die Antwort hängt davon ab, ob die Frage eine schwache oder eine starke Skalierung voraussetzt.
Aus Wikipedia :
Schwache Skalierung: Wie sich die Lösungszeit mit der Anzahl der Prozessoren für eine feste Problemgröße pro Prozessor ändert.
Starke Skalierung: Wie sich die Lösungszeit mit der Anzahl der Prozessoren für eine feste Gesamtproblemgröße ändert.
Wenn die Frage eine schwache Skalierung voraussetzt, reicht die Antwort von @ Gonzalo aus. Wenn die Frage jedoch eine starke Skalierung voraussetzt, gibt es noch etwas hinzuzufügen. Bei einer starken Skalierung wird von einer festen Workload-Größe ausgegangen. Wenn Sie also die Anzahl der Threads erhöhen, verringert sich die Größe der Daten, an denen jeder Thread arbeiten muss. Auf modernen CPUs sind Speicherzugriffe teuer und es wäre vorzuziehen, die Lokalität beizubehalten, indem die Daten in Caches gehalten werden. Daher kann die wahrscheinlich optimale Anzahl von Threads gefunden werden, wenn der Datensatz jedes Threads in den Cache jedes Kerns passt (ich gehe nicht auf die Details der Diskussion ein, ob es sich um L1 / L2 / L3-Cache (s) des Systems handelt).
Dies gilt auch dann, wenn die Anzahl der Threads die Anzahl der Kerne überschreitet. Angenommen, das Programm enthält 8 beliebige Arbeitseinheiten (oder AU), die auf einem 4-Kern-Computer ausgeführt werden.
Fall 1: Führen Sie vier Threads aus, wobei jeder Thread 2AU ausführen muss. Jeder Thread dauert 10 Sekunden ( mit vielen Cache-Fehlern ). Bei vier Kernen beträgt die Gesamtzeit 10 Sekunden (10 Sekunden * 4 Threads / 4 Kerne).
Fall 2: Führen Sie acht Threads aus, wobei jeder Thread 1AU ausführen muss. Jeder Thread benötigt nur 2 Sekunden (anstelle von 5 Sekunden, da weniger Cache-Fehler auftreten ). Bei vier Kernen beträgt die Gesamtzeit 4 Sekunden (2 Sekunden * 8 Threads / 4 Kerne).
Ich habe das Problem vereinfacht und die in anderen Antworten erwähnten Overheads (z. B. Kontextwechsel) ignoriert, hoffe jedoch, dass Sie den Punkt erreichen, dass es je nach Datengröße von Vorteil sein kann, mehr Threads als die verfügbare Anzahl von Kernen zu haben. Ich beschäftige mich mit.
quelle
4000 Threads auf einmal sind ziemlich hoch.
Die Antwort lautet ja und nein. Wenn Sie in jedem Thread viel E / A blockieren, können Sie erhebliche Beschleunigungen von bis zu 3 oder 4 Threads pro logischem Kern feststellen.
Wenn Sie jedoch nicht viel blockieren, wird der zusätzliche Overhead beim Threading nur langsamer. Verwenden Sie also einen Profiler und sehen Sie, wo sich die Engpässe in jedem möglicherweise parallelen Teil befinden. Wenn Sie umfangreiche Berechnungen durchführen, hilft mehr als 1 Thread pro CPU nicht weiter. Wenn Sie viel Speicher übertragen, hilft dies auch nicht. Wenn Sie jedoch viel E / A ausführen, z. B. für den Festplatten- oder Internetzugang, helfen ja mehrere Threads bis zu einem gewissen Grad oder machen die Anwendung zumindest reaktionsfähiger.
quelle
Benchmark.
Ich würde anfangen, die Anzahl der Threads für eine Anwendung zu erhöhen, beginnend bei 1, und dann zu etwa 100 wechseln, drei bis fünf Versuche für jede Anzahl von Threads ausführen und selbst ein Diagramm der Betriebsgeschwindigkeit im Verhältnis zur Anzahl der Threads erstellen .
Sie sollten sicherstellen, dass der Fall mit vier Threads optimal ist und die Laufzeit danach leicht ansteigt, aber möglicherweise nicht. Es kann sein, dass Ihre Anwendung bandbreitenbeschränkt ist, dh der Datensatz, den Sie in den Speicher laden, ist riesig, es treten viele Cache-Fehler usw. auf, sodass 2 Threads optimal sind.
Sie können nicht wissen, bis Sie testen.
quelle
Sie finden heraus, wie viele Threads Sie auf Ihrem Computer ausführen können, indem Sie den Befehl htop oder ps ausführen, der die Anzahl der Prozesse auf Ihrem Computer zurückgibt.
Sie können die Manpage zum Befehl 'ps' verwenden.
Wenn Sie die Anzahl aller Benutzerprozesse berechnen möchten, können Sie einen der folgenden Befehle verwenden:
ps -aux| wc -l
ps -eLf | wc -l
Berechnung der Anzahl eines Benutzerprozesses:
ps --User root | wc -l
Sie können auch "htop" verwenden [Referenz] verwenden. :
Installation unter Ubuntu oder Debian:
Installation unter Redhat oder CentOS:
Wenn Sie htop aus dem Quellcode kompilieren möchten, finden Sie es hier .
quelle
Das Ideal ist 1 Thread pro Kern, solange keiner der Threads blockiert.
Ein Fall, in dem dies möglicherweise nicht zutrifft: Auf dem Kern werden andere Threads ausgeführt. In diesem Fall können mehr Threads Ihrem Programm einen größeren Teil der Ausführungszeit einräumen.
quelle
Ein Beispiel für viele Threads ("Thread-Pool") gegenüber einem pro Kern ist die Implementierung eines Webservers unter Linux oder Windows.
Da Sockets unter Linux abgefragt werden, können viele Threads die Wahrscheinlichkeit erhöhen, dass einer von ihnen den richtigen Socket zur richtigen Zeit abfragt - aber die Gesamtverarbeitungskosten sind sehr hoch.
Unter Windows wird der Server mithilfe von E / A-Abschlussports (IOCPs) implementiert, die das Anwendungsereignis steuern: Wenn eine E / A abgeschlossen ist, startet das Betriebssystem einen Standby-Thread, um es zu verarbeiten. Wenn die Verarbeitung abgeschlossen ist (normalerweise mit einer anderen E / A-Operation wie in einem Anforderungs-Antwort-Paar), kehrt der Thread zum IOCP-Port (Warteschlange) zurück, um auf den nächsten Abschluss zu warten.
Wenn keine E / A abgeschlossen ist, muss keine Verarbeitung durchgeführt werden und es wird kein Thread gestartet.
In der Tat empfiehlt Microsoft in IOCP-Implementierungen nicht mehr als einen Thread pro Kern. Alle E / A können an den IOCP-Mechanismus angeschlossen werden. IOCs können bei Bedarf auch von der Anwendung veröffentlicht werden.
quelle
timeout is an upper bound on the amount of time elapsed before select() returns. If both fields of the timeval structure are zero, then select() returns immediately. (This is useful for polling.) If timeout is NULL (no timeout), select() can block indefinitely.
Aus rechnerischer und speichergebundener Sicht (wissenschaftliches Rechnen) führen 4000 Threads dazu, dass die Anwendung sehr langsam ausgeführt wird. Ein Teil des Problems ist ein sehr hoher Aufwand für die Kontextumschaltung und höchstwahrscheinlich eine sehr schlechte Speicherlokalität.
Es hängt aber auch von Ihrer Architektur ab. Von dort, wo ich gehört habe, sollen Niagara-Prozessoren in der Lage sein, mehrere Threads auf einem einzigen Kern mit einer fortschrittlichen Pipelining-Technik zu verarbeiten. Ich habe jedoch keine Erfahrung mit diesen Prozessoren.
quelle
Hoffe das macht Sinn, überprüfe die CPU und Speicherauslastung und lege einen Schwellenwert fest. Wenn der Schwellenwert überschritten wird, darf kein neuer Thread erstellt werden, da sonst ...
quelle