Wie geht der Windows 10-Scheduler mit Hyper Threading um, da Core Parking für Intel-CPUs standardmäßig deaktiviert ist?

2539
manuel

Ich verwende Windows 10 (1607) auf einer Intel Xeon E3-1231v3-CPU (Haswell, 4 physische Kerne, 8 logische Kerne ).

Bei der ersten Installation von Windows 7 auf diesem Computer konnte ich beobachten, dass vier von acht logischen Kernen geparkt waren, bis eine Anwendung mehr als 4 Threads benötigte. Mit dem Windows-Ressourcenmonitor kann überprüft werden, ob Kerne geparkt sind oder nicht ( Beispiel ). Soweit ich weiß, ist dies eine wichtige Technik, um die Threads über die physischen Kerne hinweg im Gleichgewicht zu halten, wie auf der Microsoft-Website erläutert : " Der Core Parking-Algorithmus und die Infrastruktur werden auch verwendet, um die Prozessorleistung zwischen logischen Prozessoren auf Windows 7-Clientsystemen auszugleichen Prozessoren, die die Intel Hyper-Threading-Technologie enthalten. "

Nach dem Upgrade auf Windows 10 habe ich jedoch festgestellt, dass es keine Kernparkplätze gibt. Alle logischen Kerne sind ständig aktiv. Wenn Sie eine Anwendung mit weniger als vier Threads ausführen, können Sie sehen, wie der Scheduler sie gleichmäßig auf alle logischen CPU-Kerne verteilt. Microsoft-Mitarbeiter haben bestätigt, dass Core Parking in Windows 10 deaktiviert ist .

Aber ich frage mich warum? Was war der Grund dafür? Gibt es einen Ersatz und wenn ja, wie sieht es aus? Hat Microsoft eine neue Scheduler-Strategie implementiert, die Core-Parking obsolet machte?


Blinddarm:

Hier ein Beispiel, wie die in Windows 7 eingeführte Kernparkfunktion die Leistung verbessern kann (im Vergleich zu Vista, für die noch keine Kernparkfunktion verfügbar war). Was Sie sehen, ist, dass HT (Hyper Threading) unter Vista die Leistung beeinträchtigt, während es unter Windows 7 nicht funktioniert:

Wie geht der Windows 10-Scheduler mit Hyper Threading um, da Core Parking für Intel-CPUs standardmäßig deaktiviert ist?

Wie geht der Windows 10-Scheduler mit Hyper Threading um, da Core Parking für Intel-CPUs standardmäßig deaktiviert ist?

( Quelle )

Ich habe versucht, Core Parking wie hier erwähnt zu aktivieren, aber ich habe festgestellt, dass der Core-Parking-Algorithmus nicht mehr Hyper-Threading-fähig ist. Es parkte die Kerne 4,5,6,7, während der Kern 1,3,5,7 geparkt sein sollte, um zu vermeiden, dass die Fäden demselben physischen Kern zugeordnet werden. Windows zählt Kerne so auf, dass zwei aufeinander folgende Indizes zu demselben physischen Kern gehören. Sehr eigenartig. Es hat den Anschein, als hätte Microsoft dies grundlegend vermasselt. Und niemand hat es bemerkt ...

Außerdem habe ich einige CPU-Benchmarks mit genau 4 Threads durchgeführt.

CPU-Affinität für alle Kerne festgelegt (Windows-Version):

Durchschnittliche Laufzeit: 17.094498, Standardabweichung: 2.472625

CPU-Affinität für jeden anderen Kern festgelegt (damit er auf verschiedenen physischen Kernen läuft, bestmögliche Zeitplanung):

Durchschnittliche Laufzeit: 15.014045, Standardabweichung: 1.302473

CPU-Affinität auf die denkbar schlechteste Planung gesetzt (vier logische Kerne auf zwei physischen Kernen):

Durchschnittliche Laufzeit: 20.811493, Standardabweichung: 1.405621

Es gibt also einen Leistungsunterschied. Und Sie können sehen, dass die Windows-Defualt-Planung zwischen der besten und der schlechtesten möglichen Planung liegt, wie wir es bei einem nicht hyperthreading-fähigen Scheduler erwarten würden. Wie in den Kommentaren darauf hingewiesen, können jedoch andere Ursachen dafür verantwortlich sein, wie weniger Kontextwechsel, Rückschlüsse durch Überwachungsanwendungen usw. Daher haben wir hier noch keine endgültige Antwort.

Quellcode für meinen Benchmark:

#include <stdlib.h> #include <Windows.h> #include <math.h>  double runBenchmark(int num_cores) { int size = 1000; double** source = new double*[size]; for (int x = 0; x < size; x++) { source[x] = new double[size]; } double** target = new double*[size * 2]; for (int x = 0; x < size * 2; x++) { target[x] = new double[size * 2]; } #pragma omp parallel for num_threads(num_cores) for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { source[y][x] = rand(); } } #pragma omp parallel for num_threads(num_cores) for (int x = 0; x < size-1; x++) { for (int y = 0; y < size-1; y++) { target[x * 2][y * 2] = 0.25 * (source[x][y] + source[x + 1][y] + source[x][y + 1] + source[x + 1][y + 1]); } } double result = target[rand() % size][rand() % size]; for (int x = 0; x < size * 2; x++) delete[] target[x]; for (int x = 0; x < size; x++) delete[] source[x]; delete[] target; delete[] source; return result; }  int main(int argc, char** argv) { int num_cores = 4; system("pause"); // So we can set cpu affinity before the benchmark starts  const int iters = 1000; double avgElapsedTime = 0.0; double elapsedTimes[iters]; for (int i = 0; i < iters; i++) { LARGE_INTEGER frequency; LARGE_INTEGER t1, t2; QueryPerformanceFrequency(&frequency); QueryPerformanceCounter(&t1); runBenchmark(num_cores); QueryPerformanceCounter(&t2); elapsedTimes[i] = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart; avgElapsedTime += elapsedTimes[i]; } avgElapsedTime = avgElapsedTime / iters; double variance = 0; for (int i = 0; i < iters; i++) { variance += (elapsedTimes[i] - avgElapsedTime) * (elapsedTimes[i] - avgElapsedTime); } variance = sqrt(variance / iters); printf("Average running time: %f, standard deviation: %f", avgElapsedTime, variance); return 0; } 
6
Halten Sie "vier von acht Kernen" fest? Sie haben gerade selbst erwähnt, dass Ihre CPU nur 4 Kerne und 8 Threads hat. Gilt "Core Parking" hier eigentlich? grawity vor 7 Jahren 1
@grawity Theoretisch war Core Parking das Mittel, damit die CPU die Hälfte des Hyperthread-Core abstellen konnte. Meines Wissens nach war der Cache pro Kern auf zwei logische (Hyperthreaded) Kerne aufgeteilt, und mit einem geparkten Cache konnte er freigegeben werden und im Wesentlichen einem einzelnen Kernzugriff auf den vollständigen Cache ermöglichen, der mit ihm verbunden war. Dies könnte einen kleinen Schub für Aufgaben mit geringer Thread-Anzahl bedeuten, während Hyperthreading weiterhin wiederhergestellt werden kann und der Kern in Multithreading-Aufgaben voll ausgenutzt werden kann. Mokubai vor 7 Jahren 1
@grawity: Sorry für die Verwirrung. Ich habe acht "logische Kerne" gemeint, dh es ist nur ein virtueller Kern. manuel vor 7 Jahren 0
@mokubai Intel-CPUs können zwei Threads auf einem einzigen CPU-Kern ausführen, was zu einer Leistungssteigerung von etwa 30% führt. Nehmen Sie jetzt jedoch an, dass Sie eine Anwendung mit zwei aktiven Threads haben. Jetzt möchten Sie, dass sie auf zwei verschiedenen physischen Kernen laufen, wodurch die Leistung im Vergleich zu Single-Thread im Idealfall verdoppelt wird. Wenn sie jedoch auf demselben physischen Kern mit Hyper-Threading ausgeführt werden, sind sie nur 30% schneller als ein einzelner Thread. Hier kommt das Core Parking ins Spiel und vermeidet die letztere Situation. manuel vor 7 Jahren 0
AMD Zen-CPUs haben ein ähnliches Problem, aber AMD hat kürzlich eine Erklärung veröffentlicht, die im Wesentlichen darauf hinweist, dass das Dienstprogramm die Leistungsprüfungen ausführte und nicht Windows selbst, basierend auf allen durchgeführten Untersuchungen. Bevor Sie also Microsoft etwas vorwerfen, überprüfen Sie, ob die Werkzeuge nicht schuld sind. Ramhound vor 7 Jahren 0
@ Emmanuel ich weiß. Wenn Sie den Core parken, wird jedoch auch ein Teil des Cache-Speichers freigegeben. Dies kann ein zusätzlicher Bonus gegenüber einem Hyper-Threaded-Core mit einem geteilten Cache sein. Mokubai vor 7 Jahren 0
@ Ramhound: Ich habe gerade meine Hypothese mit einem Benchmark getestet. manuel vor 7 Jahren 0
Core-Parking bezieht sich auf ein gesamtes physisches _core_, nicht auf einzelne logische Prozessoren. (Wenn HT aktiviert ist, haben Sie zwei LPs pro Kern; bei deaktiviertem HT haben Sie nur eine.) Begriffe wie "virtueller Kern" und "logischer Kern" sollten vermieden werden, da sie irreführend sind. Das Core-Parking wird nur dann ausgeführt, wenn _ beide LPs in einem Core für eine gewisse Zeit nicht verwendet wurden. Jamie Hanrahan vor 7 Jahren 0
@ Jamie Hanrahan: Falsch. Lesen Sie [this] (https://msdn.microsoft.com/de-de/library/windows/hardware/dn613899 (v = vs.85) .aspx), wo es heißt: _der Core Parking-Algorithmus und seine Infrastruktur werden auch verwendet Prozessorleistung zwischen logischen Prozessoren auf Windows 7-Clientsystemen mit Prozessoren, die die Intel Hyper-Threading-Technologie enthalten, ausgleichen. manuel vor 7 Jahren 0
So wird es nicht im Scheduler implementiert. Siehe die Beschreibung in _Windows Internals_ von Solomon, Russinovich und Ionescu. "Kernparken" bezieht sich auf das buchstäbliche Herunterfahren eines Kerns. Das ist auf LP-Ebene nicht möglich. Jamie Hanrahan vor 7 Jahren 0
Es ist immer noch wahr, dass der Scheduler LPs bevorzugt verwendet, so dass nur ein LP pro Kern verwendet wird. Die Thread-Planung ist jedoch extrem dynamisch und es ist sehr unwahrscheinlich, dass Ihre Testanwendung zu einem bestimmten Zeitpunkt ausgeführt werden soll. Die Tatsache, dass Ihre Test-App nur aus _nCores_-Threads besteht, aber in einem Core manchmal zwei LPs angezeigt werden, die beide die Threads Ihrer App ausführen, bedeutet nicht, dass dies nicht funktioniert. Denken Sie auch daran, dass für den Task-Manager oder für fast jedes andere Monitorprogramm mindestens ein Thread ausgeführt werden muss! Ein Blick auf das System verändert, was es tut. Jamie Hanrahan vor 7 Jahren 0
@JamieHanrahan: Tut mir leid, aber deine Aussage zum Parken ist immer noch nicht korrekt. Ich habe nachgeschlagen (Windows Internals, sechste Ausgabe, 2. Teil, S. 108), in dem es heißt: _ "Core Parking Policies [...] und lässt vor allem immer einen Thread in einem SMT-Paket ungeparkt - mit anderen Worten: Es ist dafür verantwortlich, die Hyper-Threading-Funktion von Intel-CPUs im Wesentlichen zu deaktivieren, bis das Laden dies zulässt. "_ manuel vor 7 Jahren 0
Sie lesen zu viel hinein. Ja, der Code, der dies tut, ist mit dem Code "Core Parking" verknüpft, aber der Versuch, nur eine LP in einem Core zu verwenden, ist nicht "Core Parking". Sie können keine LP aus einem Kern "parken". Eine LP ist keine physikalisch getrennte Logik, die geparkt werden kann. Es ist eine Abstraktion von 99%, die von der Mikroarchitektur präsentiert wird. Beachten Sie, dass gemäß dem MSDN-Artikel _you_ linked in Windows 7 kein Core-Parking stattfindet, nur Server 2008 ..., aber in Windows 7 nur ein LP-zu-einem-Zeitpunkt. Daher wird nur ein LP pro Core verwendet zu einer Zeit ist nicht "Kernparken". Es wird einfach keine LP verwendet. Jamie Hanrahan vor 7 Jahren 0
Nun, das ist nur eine Technik. Und es erklärt nicht, warum ich die Core-Parking-ähnliche Funktion, die in Windows 7 über Task-Manager, Ressourcenmonitor usw. funktioniert, im Gegensatz zu Windows 10, in dem sich die Prozessplanung geändert hat, und dieses hyper-Threading-freundliche Kernsystem sehen kann. Parking like Scheduling wird nicht mehr verwendet. Vielleicht müssen wir warten, bis die siebte Edition von Windows Inside veröffentlicht wird. Ich bin jedoch sehr neugierig, was genau Microsoft geändert hat, oder _or_, wenn es wirklich der Fall ist, dass die alte Vista-Planung die Leistung für <= 4-Thread-Anwendungen beeinträchtigt . manuel vor 7 Jahren 0
@manuel Es gab erhebliche Verbesserungen zwischen Windows 7 und Windows 10 Ramhound vor 7 Jahren 0
Ich weiß nicht, was Sie sehen, @manuel, aber ich sehe unter Windows 10 immer eine LP pro Kern. Ich denke, Ihr System ist nur belebter als Sie denken, also hat der Scheduler wenig Auswahl aber in einigen Kernen mehr als eine LP verwenden. Wenn Sie dieses Verhalten wirklich hassen, deaktivieren Sie einfach Hyper-Threading in Ihren Firmware-Einstellungen. Jamie Hanrahan vor 7 Jahren 0
@ Jamie Hanrahan Aber das sehe ich nicht. Und dies wird durch verschiedene Berichte im Internet bestätigt (siehe zum Beispiel [this] (https://social.technet.microsoft.com/Forums/en-US/8d6085d8-2c26-426c-87ac-2ba189b77aa5/core-parking-not -working-after-upgrade? forum = win10itprohardware)) Möglicherweise haben Sie eine AMD-CPU, da Windows 10 in diesem Fall immer noch Core Parking verwendet. manuel vor 7 Jahren 0
Nein, es ist Intel. Ich wiederhole: Sie können nicht nach dem, was Sie im Task-Manager sehen, gehen. Ich glaube, was in Windows 10 passiert ist, ist, dass der Scheduler nicht so lange hält, bevor er einen Thread auf einem Core ausführt, auf dem bereits ein Thread läuft. Jamie Hanrahan vor 7 Jahren 0
Ich glaube, dass Sie eine optische Täuschung sehen. Ich habe die Situation auf einem 8-Core-Computer mit Hyper-Threading (16 logische Kerne) überprüft und finde es sehr schwer zu sagen, wie viele Kerne geparkt sind und welche. Es scheint, als würde der Windows 10-Scheduler Kerne mit hoher Geschwindigkeit parken und entparken. Was ich in Resource Monitor sehen kann, ist der "geparkte" Zustand, der auf einigen Kernen gleichbleibend ist, auf anderen jedoch häufig flackert. Ich kann ehrlich gesagt nicht sagen, wie viele geparkte Kerne ich zu einem bestimmten Zeitpunkt habe, und ich bezweifle auch, dass die Anzeige des Ressourcenmonitors damit Schritt halten kann. harrymc vor 7 Jahren 0
@ harrymc Ich sehe nicht das "geparkt" Label im Ressourcenmonitor. Überhaupt nicht. Auch wenn sich die CPU mit <5% Auslastung im Leerlauf befindet. Ich glaube nicht, dass Ihre Theorie zutrifft, ansonsten muss der Scheduler so dumm sein, dass er häufig Kerne entparken lässt, selbst wenn mein Computer vollständig inaktiv ist, was ebenfalls ein fehlerhaftes Verhalten wäre. manuel vor 7 Jahren 0
@manuel: "fehlerhaftes Verhalten" für Sie, aber es könnte eine Logik dahinterstehen. B. die Last zwischen den Kernen aufteilen, um nicht immer einen Kern zu überarbeiten. Windows-Kernel-Entwickler kennen Intel-Hardware sicherlich besser als Sie oder ich. Überprüfung: Überprüfen Sie im Registrierungsschlüssel `HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ Power \ PowerSettings \ 54533251-82be-4824-96c1-47b60b740d00 \ 0cc5b647-c1df-4637-891a-dec35c318583` = 0`. Starten Sie neu, wenn Sie etwas ändern. harrymc vor 7 Jahren 0
Dies beantwortet Ihre Frage nicht, aber ich wette, dass Microsoft sich nicht für etwas als "Vermächtnis" wie die Haswell-Technologie interessiert. Intels Skylake hat etwas namens Speed ​​Shift eingeführt, das unter anderem das OS-gesteuerte Core Parking überflüssig macht. Die neueste Version von Windows 10 unterstützt Speed ​​Shift sehr gut. Weder Intel noch Microsoft geben viele technische Details an, aber ich denke, man kann sicher davon ausgehen, dass Microsoft Core Parking in Win 10 deaktiviert hat, da die Kernel-Architektur und -Optimierungen, die neue CPUs bevorzugen, dazu geführt haben, dass es nicht mehr mit dem mittlerweile bestehenden Core-Parking-Paradigma kompatibel ist. misha256 vor 7 Jahren 0
Vielleicht können Sie es aktivieren? ... http://www.thewindowsclub.com/enable-disable-core-parking-windows Moab vor 7 Jahren 0

1 Antwort auf die Frage

0
ZXX

Huh, ich könnte dir die Geschichte erzählen, aber du wirst es hassen und ich hasse es, sie zu schreiben :-)

Kurze Version - Win10 hat alles vermasselt, was es könnte und ist im ständigen Zustand verhungernder Kerne aufgrund von Systemproblemen, die als CPU-Überbelegung bekannt sind (viel zu viele Threads, niemand kann sie jemals bedienen, irgendetwas verschluckt sich irgendwann für immer). Aus diesem Grund werden diese gefälschten CPU-Prozessoren dringend benötigt, der Timer für den Basis-Scheduler wird auf 1 ms verkürzt und Sie können nichts parken. Es würde nur das System verbrennen. Öffnen Sie den Process Explorer und addieren Sie die Anzahl der Threads. Jetzt müssen Sie rechnen :-)

Die CPU-Sets-API wurde eingeführt, um denjenigen, die wissen und Zeit haben, den Code zu schreiben, um das Tier zu ringen, zumindest eine gewisse Chance zu geben. Sie können fake CPU-s faktisch parken, indem Sie sie in ein CPU-Set legen, das Sie nicht an Dritte weitergeben, und ein Standardset erstellen, um es in Piranhas zu werfen. Auf Client-Sku-s ist dies jedoch nicht möglich (technisch gesehen ist das einfach nicht zu rechtfertigen), da der Kernel in Panikzustand gerät und entweder CPU-Sets vollständig ignoriert oder andere Dinge zum Absturz bringen werden. Es muss die Integrität des Systems um jeden Preis verteidigen.

Der gesamte Stand der Dinge ist im Großen und Ganzen ein Tabu, da dafür umfangreiche Umschreibungen erforderlich wären und jeder das frivole Fad entließ und zugab, dass sie durcheinander geraten. Hyperthreads müssen tatsächlich dauerhaft deaktiviert werden (sie heizen die Kerne unter realer Last auf, verringern die Leistung und destabilisieren HTM - der Hauptgrund, warum es nie zum Mainstream wurde). Große SQL Server-Shops tun dies als ersten Einrichtungsschritt, ebenso Azure. Bing ist es nicht, sie betreiben Server mit De-facto-Client-Setup, da sie viel mehr Kerne benötigen, um den Wechsel zu wagen. Das Problem trat in Server 2016 ein.

SQL Server ist der einzige echte Benutzer von CPU-Sets (wie üblich :-), 99% der fortschrittlichsten Dinge in Win wurden immer nur für SQL Server ausgeführt, angefangen mit einem äußerst effizienten, mit Speicher verknüpften Dateibehandlungsprozess, durch den Linuxbenutzer seither getötet werden sie nehmen unterschiedliche Semantiken an).

Um sicher damit zu spielen, müssten Sie mindestens 16 Kerne für eine Client-Box, 32 für einen Server (das hat tatsächlich etwas Reales :-). Sie müssen mindestens 4 Kerne in die Standardeinstellung setzen, damit Kernel- und Systemdienste kaum atmen können Aber das ist immer noch ein Dual-Core-Laptop-Äquivalent (Sie haben immer noch Würgen), dh 6-8, damit das System richtig atmen kann.

Win10 benötigt 4 Kerne und 16 GB, um kaum zu atmen. Laptops kommen mit 2 Kernen und 2 falschen "CPU-s" davon, wenn nichts zu fordern ist, da ihre übliche Arbeitsverteilung so ist, dass es immer genug Dinge gibt, die sowieso warten müssen (lange Warteschlange auf Memaloc "hilft" viel :-) .

Dies wird Ihnen bei OpenMP (oder jeder automatischen Parallelisierung) immer noch nicht helfen, es sei denn, Sie haben die Möglichkeit, es explizit zur Verwendung Ihres CPU-Sets (einzelne Threads müssen dem CPU-Set zugewiesen werden) und sonst nichts zu sagen. Sie müssen auch noch die Prozessaffinität einstellen, dies ist die Voraussetzung für CPU-Sätze.

Server 2k8 war der letzte gute (ja, das bedeutet auch Win7 :-). Die Leute luden ein TB innerhalb von 10 Minuten mit SQL Server. Jetzt prahlen die Leute, wenn sie es in einer Stunde laden können - unter Linux :-) Es besteht also die Möglichkeit, dass der Zustand "da drüben" auch nicht viel besser ist. Linux hatte CPU-Sets schon lange vor Win.