Scheduler Linux/Windows - Gemeinsamkeiten und Unterschiede - Was könnte man besser handhaben?

G

Gast30082015

Guest
Hier mal ein eigener Thread für dieses interessante Thema.

Stück für Stück werd ich mal aus dem Llano-Thread einiges raus-quoten oder aber ein Mod kann die entsprechenden Beiträge gleich rüberschupsen.

Grüße und viel Spaß hier :)

Edit:
(besagte Beiträge ;)) :
Den Fehler es so zu betrachten machen wir Menschen immer wieder, da unsere Wahrnehmung immer auf Zeitabschnitte ausgelegt ist. Ein Scheduler hat aber keinen Überblick über den Zeitabschnitt, sondern muss aufgrund der Faktenlage zu einem Zeitpunkt entscheiden.

Der Scheduler zieht die Tasks nicht freiwillig um, sondern ist dazu gezwungen. Das Problem entsteht folgendermaßen: nimm an, der Scheduler muss monoton nach 10ms die Tasks schedulen, heißt er bekommt nach 10ms einen Timer-Interupt und muss entscheiden welche Tasks laufen dürfen. Nun hast du 4 Kerne aber angenommen 5 Threads, welche laufen wollen, dein 100% Load Thread läuft und 3 andere Hintergrundthreads auch.
Zum Zeitpunkt der Entscheidung wollen alle noch laufen, also nimmt der Scheduler einen laufenden Thread raus und gibt einem anderen das Recht auf einem Kern zu laufen. Da alle Threads die gleiche Prio haben erwischt es halt per Zufall gerade deinen 100% Thread. Zum nächsten Entscheidungszeitpunkt meldet einer der laufenden Hintergrundtasks, dass er nicht mehr laufen will, es wird also ein Kern frei. Da alle anderen Threads weiter laufen wollen, migriert der Scheduler natürlich nicht alle laufenden Threads auf einen anderen Kern, sondern lässt sie weiterlaufen. Dein 100% Thread bekommt einfach den freien Kern, wenn es der Kern ist, auf dem er vorher war hast du Glück, ansonsten hat mal wieder die Statistik zugeschlagen.

Was lernen wir daraus: wenn du wirklich einen Thread bzw. Prozess hast, der möglichst viel Rechenzeit bekommen und wenig Migriert werden soll, musst du die Prio hochsetzten, um die Chancen zu verringern, dass dein Prozess überhaupt beim Scheduling als Kandidat für das unterbrechen in Frage kommt. Keine Unterbrechung -> kein Kernwechsel.

Der Scheduler bekommt nur die Information vom Thread: "hey ich habe Arbeit, bitte gib mir die CPU". Der Scheduler weiß nicht, ob das ein Hintergrundthread ist. Er kann also nur entscheiden: habe ich Ressourcen um den Thread laufen zu lassen, oder muss ich ihn nach hinten stellen. Der Scheduler kann es sich nicht leisten einen Thread zu verzögern, nur weil dieser in der Vergangenheit keine großen CPU Anforderungen hatte, das kann sich in der Zukunft ändern. Oder würde es dir gefallen, wenn dein Virenscannerprozess die Datei, welche du gerade brauchst, extrem langsam bearbeitet, weil er vorher im Hintergrund auf Arbeit gewartet hat und deshalb vom Scheduler nur wenig Zeit zugeteilt bekommt?

Die einzige sinnvolle Möglichkeit hier ist die Prioritäten der Prozesse im System richtig zu setzen. Leider tun die meisten hier das intuitiv richtige und pinnen den Prozess auf einen Kern, statt das objektiv sinnvolle Anpassen der Prioritäten vorzunehmen.
.
EDIT :
.



Bitte nicht wieder mit geglätteten Durchschnittswerten arbeiten. Der Scheduler muss zu einem Zeitpunkt entscheiden, weshalb er nur einen Datensatz hat, keinen Durchschnitt.

So kann es sehr wohl vorkommen, dass auf einem System mit Durchschnittsload < 1 zu einem Zeitpunkt mehr Threads laufen wollen, als Kerne vorhanden sind. Und in diesem Fall kann es zum Kernhopping kommen. Das habe ich ja vorhin versucht zu erklären, auch bei nur einem Lastthread und 4 Kernen kann der Scheduler gezwungen sein den Prozess zu migrieren. Der Linux CFQ Scheduler hat sehr viel Logik um ungünstige Migrationen zu verhindern (schätzungsweise 80% des Schedulercodes), trotzdem lässt es sich nicht ganz umgehen.

Die Frage ist doch aber, warum das BS dies nicht selber hin bekommt.

Warum kann der Scheduler nicht abschätzen, dass ein Prozess, der die letzten 10 Sekunden schon einen Kern voll ausgelastet hat, dies höchst wahrscheinlich auch die nächsten 10 Sekunden tun wird. Warum teilt er unwichtige kleine Prozesse nicht ausschließlich den gering ausgelasteten Kernen zu. Für mich arbeitet der Windows Scheduler noch mit der Logik aus der Single-Core-Zeit. Wenn ich beim Bulldozer künftig 8 "Integer-Kerne" im Angebot habe, macht die alte Logik für mich keinen Sinn. Ich habe immer viele Prozesse, die gleichzeitig laufen. Warum muss das aber dazu führen, das der fordernste und zeitkritischste ständig einem anderen Kern zugewiesen wird? Das sollte doch eigentlich ein lösbares Problem sein. *noahnung*
Weil der Scheduler keine Information über die Vergangenheit hat. Weder kann er im Kernel die benötigten Durchschnittswerte errechnen (kein Float Code im Kernel), noch kann soviel Speicher für einen Kernelteil verbraten werden (alleine dadurch würde der Scheduler, der alle 10ms läuft den Applikationen die Daten aus dem Cache kegeln). Außerdem muss der Scheduler innerhalb weniger µs eine Entscheidung treffen, der kann nicht erst 1ms rumrechnen bis er weiß welcher Thread auf welchem Kern laufen darf, damit wären 10% der verfügbaren Rechenzeit schon totgelegt.

Deshalb muss man dem Scheduler halt Tipps geben. Wie gut (Linux) oder schlecht (Windows) der Scheduler mit diesen Tipps umgeht, darüber kann man sich streiten, aber nicht über die Grundlagen der Schedulerlogik.

Ich hab damit kein Problem, aber machen die OS nicht seit Generationen im Namen der "Benutzerfreundlichkeit" nicht genau das Gegenteil? - An allen Ecken und Kanten wird dem User das Denken abgenommen, man muss nichts mehr einstellen. Es läuft "Out of the box" - das ist doch auch genau der Punkt wo die Desktop-Linuxe hinwollen.
Warum ist das Mainstream-OS dann zu Dusselich seine Systemprozesse mit niedrigerer default-Prio zu starten?
Unter Linux gibts vieviele Nice-Level? 20?
Es war unter Kernel 2.4 Mode den X-Server mit Nice -10 zu starten, damit er deutlich höher Priorisiert ist als der Rest des Systems. Ergo könnte man genausogut die Startskripte so auslegen dass sie die Hintergrundprozesse auf einem Desktopsystem mit Nice 2 oder sowas starten, das wäre minimal niedriger priorisiert als normale Prozesse, aber im Zweifelsfall hätte mein Programmthread vorrang.
Analog könnte sowas unter Windows laufen. - Die Scheduler-Logik ist also bereits da, man müsste sie nur per default anders umsetzen.
Und ich rede dabei nicht von cinebench oder so Benchmark-Kram. Aber spätestens wenn ich ein Video gucke und das Ruckelt nur weil irgend ein blöder 0815 Hintergrundprozess der genausogut später noch laufen könnte, mir die CPU-Rechnezeit stiehlt, hat das nichts mit mehr Effizienz zu tun.
Die Hauptaufgabe eines PCs ist mir, dem Benutzer zu dienen und nicht dem System als solches. *noahnung*
Nun aber genug OT....
Da teile ich deine Meinung. Die Frage über die hier diskutiert wurde war allerdings, ob der Scheduler intelligenter werden muss/kann. Und das ist eindeutig nicht der Fall. Das die Betriebssysteme insgesamt in dem Bereich besser werden müssen ist auch nicht zu bestreiten, deswegen der Verweis auf die Möglichkeit so etwas an die Distribution zu melden.

Bei den meisten gibt es nur immer diese Kurzschlussreaktion: der Scheduler ist für die Verteilung der Arbeit zuständig, die Arbeit wird nicht optimal verteilt (z.B. Kernhopping) -> großer Aufschrei, der Scheduler muss besser werden. Das ist einfach nur platt.
Ok, dann haben wir aneinander vorbeigeredet.
Ich wollte eigentlich darauf hinweisen dass die Scheduler intelligent genug sind, also die Strukturen bereits da. Dass wir diese nicht nutzen ist Dummheit/Faulheit/Nachlässigkeit/Ignoranz/<Bezeichnung bitte einsetzen>

Dazu ist Hardware einfach zu billig. Bevor man Entwicklerstunden für derariges "Tuning" opfert, kauft man lieber eine schnellere CPU und verlässt sich auf Moores Law. *noahnung*
.
EDIT :
.



Ist ja auch sinnvoll, der Kernel hat das Grouping ja auch erst kürzlich gelernt.
Imho geht der Ansatz in die richtige Richtung. Ist aber eben noch zu wenig verbreitet (un ich frage mich warum es erst 30 Jahre PC-Geschichte bedarf um auf so eine Idee zu kommen? ??? )
Du musst doch die Programme garnicht ändern... sondern nur dafür sorgen (über welche API auch immer) dass die Prozesse die sich als Systemdienste registrieren mit Nicelevel laufen, oder wie auch immer man das unter Windows nennt... eben eine Stufe weniger wichtig als die "normalen" Anwendungen.
*noahnung*
Da muss garkein Programm irgendwas selbst festlegen.
Das Sahnehäubchen wäre dann sowas wie Systemprozesse 2 stufen niedriger, minimierte Fenster eine stufe und das womit ich grade arbyte eben normalprio.
Dann hätte man das Chaos sortiert, Priorisiert und ich hätte manuell immer noch die Möglichkeit zu sagen "Programm xyz pinne ich auf höchste Prio, auch wenns im Hinterrund läuft weil...."
Aber dass der Flash-Update-Checker und die tausend kleinen "ich telefonier grad mal heim zum gucken was die Woche so los ist" - Routinen mir als Benutzer die Rechenzeit stehlen ist einfach nur autsch. *noahnung*
Nennt mich pingelig wenn ihr wollt. Aber wenn man schon um 10% Leistung hin oder her stundenlang diskutieren kann, wenn Benchmarks anhand von Zahlenwerten die sowieso eng beieinander liegen zerpflückt werden usw. Dann darf man auch mal die Effizienzkeule auspacken und sich fragen warum wir mit der Rechenzeit unserer CPUs so verschwenderisch umgehen. Oder besser gefragt, warum bin ich als zahlender Kunde, meine Wünsche und die Programme die ich grad bediene nicht wichtiger als irgend ein Hintergrundprozess xyz, den ich womöglich nicht mal kenne! *noahnung*
 
Zuletzt bearbeitet:
Wie währe eine Art Bewertungs- bzw Auswahlsystem, welche Appllikationen/Trieber/Dienste in welcher Prioklasse Arbeiten dürfen.
Ich stelle mir das so vor, dass alle Programme, welche eh im hintergrund laufen (eben Treiber, Virenscaner, etc) in einer eigenen Prioritätsklasse laufen, und diese immer niedriger ist, als die Klasse der offen ausgeführten Programme. Innerhalb der Klassen gäbe es natürlich auch verschiedene Prioritätslevel, um bspw. die Idee mit den Minimierten Fenstern aufzugreifen. Als Dritte Klasse dann noch die Systemklasse à la Kernelfunktionen, Systemprozesse etc.

Soweit ich weiss muss/sollte man seinen Treiber bei microsoft signieren lassen (z.B. Grafiktreiber). In diesem Durchgang könnte man gleich die Einteilung in die Enstprechende Klasse vornehmen, wobei die keinerlei Einfluss haben, also z. b. Ein HP Druckertreiber nie in die Applikationsklasse kommen könnte.

Sinn des ganzen: Saubere Durchpriorisierung aller laufenden prozesse.

Frage: Ist dies überhaupt durchführbar? Soweit ich die Diskusion über den WinScheduler verstanden habe, sollte dieser das mit einer nicht allzu grossen Überarbeitung (einfügen von Kalssen) Hinbekommen.

Diskusionen erwünscht ;)

mfg memory_stick
 
Da wäre wohl eine Anpassung nötig...
Aber eigentlich nicht am Schedulercode selber, denn der sieht nur "welche prio hat der thread" - und handelt danach. Die Einteilung geschieht beim Laden des Programms oder eben später durch den Taskmanager.
Kerneltreiber würde ich Prio-Technisch eher nicht anrühren, da hängt zuviel dran, irgendwelche Reaktionszeiten der Hardware usw.
Aber wenn man so in die "Dienste" - Liste in der Computerveraltung guckt, was sich da so alles tummelt.... Das muss doch nicht alles mit User-Prio laufen. Hier bedürfte es meiner Auffassung nach nur einer Anpassung an dem Mechanismus der diese Systemdienste der Reihe nach startet, bzw. der API-Aufruf der das erledigt, die Programme müssen sich ja irgendwo eintragen damit sie in der Liste auftauchen, das System weiss also dass das Dienste (und damit per se Hintergrundprozesse) sind.
Genau hier würde ich fürs erste den Hebel ansetzen. Alles das da kreucht und fleucht erstmal 1 prio-Ebene niedriger laufen lassen als die normalen Programme die ich selbst ausführe.
Dann das Ganze Systemtray-Gedöns- entweder automatisch oder nach dem Starten über irgend eine Funktion niedriger priosisieren, im Prinip ein Shortcut für "Taskmanager öffnen, Prozessname suchen, niedrige Prio einstellen" - und das mit jedem dieser Pappenheimer.
Das mit dem minimierten Fenster ist nur das i-tüpfelchen und unter Umständen kontraproduktiv wenn die minimierte App z.B. Winamp ist und dann plötzlich stockt weil Firefox grade eine größere Webseite lädt.
Ebenso könnte man sich eine Tastenkombination denken, eine oder 2 tasten gedrückt halten und das fenster anklicken um den prozess höher oder niedriger zu priorisieren. Das wäre wesentlich einfacher und schneller als der Weg über den Taskmanager.

Sogesehen sind einige Szenarien hier denkbar... wie Aufwändig das eine oder andere wäre, kann ich nicht genau beziffern. Manches davon mag problematisch sein weil die UAC erstmal fragen würde ob ich die prio-Änderung gestatten will oder sowas. *noahnung*
 
Wie wäre es, wenn all diese Dienste sich einen Kern teilen, sofern nicht viel Arbeit gefordert ist?
Dann können auf den anderen Threads Benutzerprogramme laufen. Oder ähnlich dem Tegra 3. Einem zusätzlichen Core, der eben diese niedrigeren Prioritäten behandelt. Glaube kaum, dass einer dieser Threads so rechenintensiv ist. So könnte man auch Strom sparen, wenn im Idle alle Threads auf einem langsamen und sehr effizienten Kern laufen und der Rest gepowergated wird.
Wenn dann Power gefragt wird, werden die Threads auf die rechenstarken Kerne ausgelagert.
 
naja,d as kommt auf die Applikation an, pauschal davon auszugehen dass Hintergrunddienste nicht viel Rechenzeit benötigen ist gefährlich...
Virenscanner, Windows-Suchindex, geschweige denn irgendwelche Datenbnakdienste oder webserver auf einer Workstation... *schulterzuck*
 
Zurück
Oben Unten