Hallo zusammen,
aus meinem anderen Thread stellt sich für mich eine reine Interessens- Frage, die ich aber sicherheitshalber separat stelle, um ungünstige Vermischungen zu vermeiden.
Wenn ich einen Sechs-Core-Prozessor habe, erscheint dieser im System als 12 CPUs, in Tools wie htop auch als 12 ganz unabhängige Einheiten. Tatsächlich sind das aber *sechs* unabhängige Teile, die jeweils zwei Threads verwalten können, richtig?
Das heißt, wenn mein System mehr als 12 Prozesse laufen hat (also immer), dann muss das System nicht wirklich reihum wechseln wie früher bei einem Single-Core-Prozessor, sondern kann einige Prozesse wirklich nebeneinander laufen lassen, richtig?
Nicht ganz klar ist mir hier das Verhältnis von "echten" Cores und Threads. Ich stelle mir vor, dass ein Core eine Möglichkeit hat, zwei Prozesse effizienter zu verwalten als wenn er nicht diese Thread-Unterstützung hat. Aber *ein* Prozess, der einen Core zu 100% in Beschlag nimmt, müsste doch effizienter sein als *zwei* Prozesse, die sich diesen Core "teilen" und ständig hin- und her wechseln müssen?
Meine Frage bezieht sich letztlich auf die Aufgabe, mehrere Compiler- Prozesse parallel laufen zu lassen. Compiler wollen ja immer die ganze Rechenleistung haben, je mehr sie davon haben, desto schneller werden sie fertig (anders als z.B. User Interfaces, wo man sich gerade das nimmt, was gerade gebraucht wird und dann wartet, bis der Nutzer mal wieder wo drauf klickt).
Wenn ich also das Beispiel aus meiner anderen Frage nehme und sehr viele Compiler-Prozesse starten will, dann müsste das doch eigentlich am allerschnellsten gehen, wenn jeder Compiler-Prozess *eine* Core zu 100% beansprucht. Wenn ich also idealisiert sagen könnte: Starte vier Compiler und nutze dafür vier Cores, dann sollte das besser sein als: Starte acht Compiler und nutze die acht Threads von vier Cores.? Mir ist klar, dass das OS (zumindest von selbst) die Hunderte oder Tausende Prozesse, mit denen es sonst noch beschäftigt ist, sowohl auf die verbleibenden zwei Cores verteilt und bestimmt auch noch Zyklen von "meinen" vier Cores abzweigt.
So, bei alledem geht es mir zunächst mal darum, Feedback zu bekommen, das mein Verständnis dieser Dinge verbessert. Zusätzlich würde mich aber auch noch konkret interessieren, ob es möglich ist, Prozesse so zu steuern bzw. zu starten, dass ich etwa das OS anweise, für einen Compilerprozess einen ganzen Core, am besten exklusiv, zur Verfügung zu stellen. Wenn das möglich sein sollte, dann würde ich z.B. versuchen, meine Compilersysteme so zu arrangieren, dass ich meine Tausende Kompilierprozesse (je nachdem, was ich grade sonst noch so mit dem Rechner vorhabe) auf 4 oder 5 der 6 Cores exklusiv zu starten, anstatt dafür zu sorgen, dass immer 8 oder 10 Jobs aktiv sind.
Ich weiß nicht, ob diese Diskussion irgendwo hin führen kann, aber falls ja, wird es nicht nur Auswirkungen auf meinen Bürorechner haben, sondern in Frescobaldi (https://frescobaldi.org) - die wichtigste LilyPond-IDE - eingehen.
Herzliche Grüße Urs
Prozessorkerne sind heute sehr komplexe Gebilde. Sie bestehen aus vielen einzelnen Modulen, die für unterschiedliche Aufgaben zuständig sind. Nicht jedes Programm lastet ständig alle dieser Module voll aus. Wenn beispielsweise ein Programm gerade nichts mit Fließkommazahlen zu rechnen hat, dann liegt das entsprechende Modul brach. Wenn man Multithreading aktiviert, und wenn auch tatsächlich gerade viele Prozesse gleichzeitig auf Prozessorleistung warten, dann versucht der Prozessor, solche brachliegenden Module sinnvoll zu nutzen, indem er auf einem Kern zwei Prozesse gleichzeitig laufen lässt. Dabei kann es vorkommen, dass diese Prozesse sich fast nicht gegenseitig stören, und somit nahezu die doppelte Anzahl Prozesse gleichzeitig laufen kann. Es kann natürlich auch vorkommen, dass zwei Prozesse gleichzeitig das selbe Modul nutzen möchten, in diesem Fall muss einer kurz warten. Daher läuft ein einzelner Prozess schneller, wenn er der einzige Prozess auf dem Prozessorkern ist, aber alles ist insgesamt schneller, wenn man Multithreading aktiviert, jedoch nicht so schnell, als wenn man wirklich die doppelte Anzahl Prozessorkerne hätte.
Ergänzung: wegen der diversen CPU-Sicherheitslücken der letzten Jahre ist derzeit auf einigen Systemen Multithreading deaktiviert.
Hallo,
Wenn ich einen Sechs-Core-Prozessor habe, erscheint dieser im System als 12 CPUs, in Tools wie htop auch als 12 ganz unabhängige Einheiten. Tatsächlich sind das aber *sechs* unabhängige Teile, die jeweils zwei Threads verwalten können, richtig?
Wenn man es hinreichend low-level betrachtet, ja.
Der CPU-Core hat bei HT/SMT den Registersatz und Teile des Steuerwerks doppelt. Das Rechenwerk und die I/O Leitungen sind aber nur einmal vorhanden. Im wesentlichen führt HT/SMT dazu, dass der eine Thread rechnen kann, während der andere auf I/O (RAM bzw. 3rd Level Cache Zugriffe) wartet.
Nicht ganz klar ist mir hier das Verhältnis von "echten" Cores und Threads. Ich stelle mir vor, dass ein Core eine Möglichkeit hat, zwei Prozesse effizienter zu verwalten als wenn er nicht diese Thread-Unterstützung hat.
Ja. Dadurch, dass der Registersatz doppelt vorhanden ist, muss bei einem "Wechsel" müssen bei einem Wechsel zwischen den beiden Threads nicht erst die Register auf dem Stack gesichert werden, wie das bei einem Multitasking auf einem System mit nur einem Thread nötig wäre.
Aber *ein* Prozess, der einen Core zu 100% in Beschlag nimmt, müsste doch effizienter sein als *zwei* Prozesse, die sich diesen Core "teilen" und ständig hin- und her wechseln müssen?
Nein. Denn erstens kostet das "Hin und her wechseln" keine Zeit, die CPU macht das automatisch ohne Zutun des Betriebssystems. Und zweitens warten die meisten Prozesse zu einem gewissen zeitlichen Anteil auf Zugriffe auf das RAM bzw. den L3 Cache. In diesen Zeiten ist das Rechenwerk ungenutzt. HT sorgt dafür, dass dann ein anderer Thread diese Ressource nutzen kann.
Wie viel das tatsächlich bringt, hängt vom Anwendungsfall ab. Das eine Extrem wäre ein Prozess, der in einem eng begrenztem Adressbereich laufend FPU Berechnungen ausführt; z.B. das Berechnen von Fraktalen. Dieser lastet das Rechenwerk zu nahezu 100% aus und wartet selten auf das RAM. Das andere Extrem ist ein Prozess, der über einen großen Speicherbereich iteriert und darin keine aufwändigen Operationen macht; z.B. eine Stringsuche in einem großen Text. Dieser wartet ständig auf RAM-Zugriffe, so dass das Rechenwerk oft brach liegt.
Prozesse dieser beiden Bauarten lassen sich gut mit HT auf einem Core kombinieren. In der Realität sind die Workloads nicht so extrem, aber das Prinzip bleibt das gleiche.
Meine Frage bezieht sich letztlich auf die Aufgabe, mehrere Compiler- Prozesse parallel laufen zu lassen. Compiler wollen ja immer die ganze Rechenleistung haben, je mehr sie davon haben, desto schneller werden sie fertig (anders als z.B. User Interfaces, wo man sich gerade das nimmt, was gerade gebraucht wird und dann wartet, bis der Nutzer mal wieder wo drauf klickt).
Wenn ich also das Beispiel aus meiner anderen Frage nehme und sehr viele Compiler-Prozesse starten will, dann müsste das doch eigentlich am allerschnellsten gehen, wenn jeder Compiler-Prozess *eine* Core zu 100% beansprucht. Wenn ich also idealisiert sagen könnte: Starte vier Compiler und nutze dafür vier Cores, dann sollte das besser sein als: Starte acht Compiler und nutze die acht Threads von vier Cores.? Mir ist klar, dass das OS (zumindest von selbst) die Hunderte oder Tausende Prozesse, mit denen es sonst noch beschäftigt ist, sowohl auf die verbleibenden zwei Cores verteilt und bestimmt auch noch Zyklen von "meinen" vier Cores abzweigt.
Ob das so stimmt, hängt von der Programmiersprache und dem verwendeten Compiler ab. Bei C/C++ und dem GCC ist es typischerweise so, dass es am schnellsten geht, wenn man die vorhandenen Threads zu ca. 50% überbucht, d.h. in deinem Fall 12 parallele Tasks startet. Der Grund ist, dass GCC viele Zwischenergebnisse in temporären Dateien speichert und damit die einzelnen Tasks zu einem gewissen Grad auf File-I/O warten. Das genaue Optimum hängt aber von sehr vielen Parametern ab, wie dem genutzten Datenspeicher, dem vorhandenen RAM, der Geschwindigkeit des RAM-Zugriffs, der GCC-Version und der verwendeten Optimierungen. Daher hilft letztlich nur ausprobieren, um den optimalen Wert zu finden.
Andere Compiler (z.B. Java oder Go) arbeiten mit wesentlich weniger File-I/O und performen daher besser mit weniger Tasks.
Gruß, Harald