Scheduling Teil 2 Prof. Dr. Margarita Esponda Freie Universität Berlin WS 2011/2012 Multilevel Feedback Queue Scheduling Vier Prioritätsklassen Beispiel: neue Prozesse Quantum = 4 Höchste Priorität Quantum = 8 Quantum = 16 FCFS Niedrigste Priorität Die Prozesse wandern mit der Zeit nach unten. Niedrigere Priorität, aber größere Quantum. M. Esponda-Argüero Multilevel Feedback Queue Scheduling Parameter: - Anzahl der Warteschlangen. - Scheduling-Algorithmen für jede Warteschlange. - Wann können Prozesse zwischen den Warteschlangen wandern. - Wo werden neu gestartete Prozesse eingeordnet. - Wie oft wird Scheduling-Information aktualisiert - Welches Feedback wird verwendet. M. Esponda-Argüero BSD 5.2-Scheduler "multilevel feedback queue scheduler" ✴ Dynamische Prioritäten ✴ nice-Wert. Nettigkeit eines Threads gegenüber den anderen. -20 ich bin nicht nett und will mehr CPU-Zeit der Prioritätszerfall wird gebremst 0 er will gleich bleiben 20 ich bin sehr nett und gibt CPU-Zeit ab die Prioritätszerfall wird beschleunigt M. Esponda-Argüero BSD 5.2 - Scheduler Scheduling-Klassen Priorität Klasse Thread-Type 0 - 63 ITHD Botton-half kernel (Interrupt) 63 - 127 KERN Top-half kernel 128 - 159 REALTIME Real Time 160 161 162 160 - 223 TIMESHARE 224 - 255 IDLE Time-sharing user Idle user . . . . . . 222 223 M. Esponda-Argüero BSD 5.2 Scheduler "multilevel feedback queue scheduler" ✴ 64 verschiedene Prioritäten in der Time-sharing-Klasse von 160 (PRI_MIN_TIMESHARE) bis 223 (PRI_MAX_TIMESHARE) ✴ In jedem 4. Zeit-Quantum (ca. 40 Millisekunden) werden die Prioritäten neu berechnet ✴ die Prioritäten fallen linear in Bezug auf die verbrauchte CPUZeit ✴ negative nice-Werte verspäten der Zerfall der Priorität von rechenintensiven Threads ✴ Ein-/Ausgabe intensive Threads werden favorisiert M. Esponda-Argüero BSD-Scheduler Berechnung der Prioritäten im BSD 5.2 Die Prioritäten werden mit Hilfe der nice und recent_cpu Komponenten der Thread-Struktur berechnet. recent _ cpu user _ priority = PRI _ MIN _ TIMESHARE − + 2 ⋅ nice 4 Wobei - nice vom Benutzer gesetzt wird, - recent_cpu mit einem exponentiell gewichteten gleitenden Durchschnitt approximiert wird - und PRI_MIN_TIMESHARE = 160 M. Esponda-Argüero BSD-Scheduler Berechnung der Prioritäten Berechnung des recent_cpu eines Threads: ✴ pro Tacktzyklus (clock tick) wird recent_cpu um 1 inkrementiert, wenn das Thread gerade ausgeführt wird ✴ jede Sekunde wird in Abhängigkeit der durchschnittlichen Anzahl der Threads (avg_load) des Systems eine Korrektur gemacht recent _ cput = 2 ⋅ avg _ loadt recent _ cput −1 + nice 2 ⋅ avg _ loadt + 1 avg_load ist die durchschnittliche Anzahl von Threads (run-queue + wait-queue) in den letzten 60 Sekunden. avg _ loadt ∑ = i =t − 60 i =t length(run _ queue i ) + length(wait _ queuei ) 60 M. Esponda-Argüero BSD 5.2 -Scheduler Berechnung der Prioritäten Wenn ein Thread gerade aus dem Warte-Zustand raus kommt, wird seine recent_cpu wie folgt berechnet: ⎛ 2 ⋅ avg _ loadt ⎞ recent _ cput = ⎜ ⎝ 2 ⋅ avg _ load + 1 ⎟⎠ sleep _ timet recent _ cput −1 + nice t M. Esponda-Argüero BSD 5.2 - Scheduler Nehmen wir an, wir haben nur ein Thread mit nice = 0 und Ti = akkumulierte Tackt-Zyklen (Ausführungszeit) innerhalb des Zeitintervalls i 2 recent _ cpu = T0 = 0, 66 ⋅ T0 3 recent _ cpu = 0, 66 ⋅ (T1 + 0, 66 ⋅ T0 ) = 0, 66 ⋅ T1 + 0, 44 ⋅ T0 recent _ cpu = 0, 66 ⋅ T2 + 0, 44 ⋅ T1 + 0, 30 ⋅ T0 recent _ cpu = 0, 66 ⋅ T3 + 0, 44 ⋅ T2 + 0, 30 ⋅ T1 + 0, 20 ⋅ T0 recent _ cpu = 0, 66 ⋅ T4 + 0, 44 ⋅ T3 + 0, 30 ⋅ T2 + 0, 20 ⋅ T1 + 0,13 ⋅ T0 Nach fünf Berechnungen wird der CPU-Verbrauch vor 5 Sekunden fast vergessen. M. Esponda-Argüero Lotterie-Scheduling - von Waldspurger und Weihl - 1994 entwickelt - Der Grundgedanke ist hier, einem Prozess Lotterielose für verschiedene Ressourcen (z.B. CPU-Zeit) zu geben. - Wer eine bestimmte Ressource bekommt, wird beim Ziehen eines Lotterieloses entschieden. - Prozesse mit höherer Priorität bekommen Extra-Lose. M. Esponda-Argüero Lotterie-Scheduling Interessante Eigenschaften • Kooperierende Prozesse können Lose austauschen. • Ein gerade blockierter Client-Prozess kann seine Lose an den ServerProzess abgeben. • Server-Prozesse brauchen keine Lose, wenn keine Client-Prozesse vorhanden sind. • Einige Probleme lassen sich einfacher als mit anderen Methoden lösen . • Alle Prozesse haben eine Mindestanzahl von Losen, so dass keiner verhungern kann. M. Esponda-Argüero "Hybrid Lottery Scheduling" D. Petroe, K. Milford und G. Gibson • Kombination der Priorität-Klassen des BSD-Scheduling mit der Lottery-Scheduling • Dynamische Anpassung der Lose mit Hilfe von Lose-Währungen • Der Overhead ist größer und die Implementierung komplexer Literatur-Empfehlung: Implementing Lottery Scheduling: Matching the Specializations in Traditional Schedulers David Petrou, Kohn W. Milford und Garth A. Gibson 1999 M. Esponda-Argüero Stride-Scheduling ✴ Waldspurger and Weilhl, 1995 ✴ deterministisches fair-share-Scheduling ✴ Tickets anstatt Lotterie-Lose ✴ Viele Tickets bedeute mehr Recht auf CPU-Zeit ✴ Ressourcen werden direkt proportional zur Anzahl von Tickets zugeteilt. z.B. Ein Prozess, der 10 Tickets hat, bekommt innerhalb einer bestimmten Zeitspanne doppelt so viel CPU-Zeit als einer, der nur 5 Tickets hat. ✴ die Prozesse bekommen immer das gleiche CPU-Quantum ✴ ein Zeitintervall stride, das ein Prozess zwischen den CPUZuteilungen warten muss, wird berechnet. M. Esponda-Argüero Stride-Scheduling Einfaches Konzept - CPU-Kapazitäten werden von Prozessen reserviert (Tickets). - Ein Ticket stell eine minimale CPU-Zeiteinheit dar. - Jeder Prozess hat ein pass-Wert, der dynamisch berechnet wird. - Der pass-Wert wächst umgekehrt proportional zu den reservierten CPU-Kapazitäten. - Das Inkrement des pass-Werts wird stride genannt. stride1 strideTi = ticketsTi Beispiel: stride1 = 20 M. Esponda-Argüero Stride-Scheduling stride1 Beispiel: stride1 = 20 Am Anfang ist der pass-Wert = 0 für alle Prozesse Der Scheduler wählt den Prozess mit dem kleinsten pass-Wert strideTi = ticketsTi Stride-Scheduling Quantum A B C C C A C C A B C Was passiert, wenn neue Prozesse gestartet oder beendet werden? Ein pass-Wert muss berechnet werden. In dem System gibt es einen globalen pass-Wert der aktualisiert wird, indem ein globaler stride-Wert addiert wird. global _ stride = stride1 global _ tickets passTnew = global _ pass + strideTnew M. Esponda-Argüero Stride-Scheduling Prozesse haben auch eine remain-Komponente, die wie folgt berechnet wird: remain = passTi − global _ pass Prozesse, die aus der Warteliste neu gestartet werden, müssen nur ihre remain-Komponente zum globalen pass-Wert addieren, um ihren eigenen pass-Wert zu berechnen. Wenn ein Prozess unterbrochen wird, wird ihr pass-Wert mit folgender Formel berechnet. timeconsumed passTi = passTi + ⋅ strideTi timeallocated M. Esponda-Argüero Stride-Scheduling Anfangszustand der Warteschlangen pass HEAD 0 A 1 2 2 B C 3 5 Tickets . . . n 0 . . . HEAD 6 C . . . 10 pass A B C C B C A C B C 15 10 6 12 20 18 30 24 30 30 time B . . . 15 . . . A M. Esponda-Argüero Früheres Linux-Scheduling Der O(1)-Scheduler - SMP (Symmetric Multiprocessing) - Prozessor Affinität - Lastverteilung - Unterstützung von interaktiven Threads Quantum Priorität - real-time-Bereich - nice-Bereich 0 - 99 100 - 140 Höhere Prioritäten Niedrige Prioritäten 200 ms. … 10 ms. Höhere Prioritäten haben ein längeres Zeitquantum. Niedrigere Prioritäten haben ein kürzeres Zeitquantum. Echtzeit-Tasks bekommen immer eine feste Priorität. Prozesse (Threads) im nice-Bereich haben dynamische Prioritäten, die sich um ±5 verändern können. M. Esponda-Argüero Linux-Scheduling (früher) Linux hatte zwei Listen nach Prioritäten sortiert. Aktive Tasks Ausgelaufene Tasks [0] [0] [1] [1] [2] [2] . . . [140] . . . . . . . . . [140] Tasks, die unterbrochen werden, oder deren Quantum ausgelaufen ist, werden zum Array der ausgelaufenen Tasks geschickt und ihre Priorität wird neu berechnet. Wenn die Liste der aktiven Tasks leer ist, werden beide Listen vertauscht. M. Esponda-Argüero Completely Fair Scheduler Neuer Scheduler von Linux. Alle Prozesse (mit verschiedenen Prioritäten), die im BereitZustand sind, werden mit einem einzigen R/B-Baum verwaltet. Jede CPU hat einen eigenen Scheduler mit einem eigenen R/BBaum. Die Prozesse werden in den Baum nach einer sogenannten virtuellen Zeit einsortiert, die vom Scheduler jedes Mal neu berechnet wird. M. Esponda-Argüero Completely Fair Scheduler früher Prozesse A B C Gewichte 4 3 1 4/8 3/8 1/8 Summe = 8 CPU Zeit M. Esponda-Argüero Completely Fair Scheduler Prozesse A B C Gewichte 4 3 1 4/8 3/8 1/8 100% 100% Summe = 8 CPU Zeit 100% M. Esponda-Argüero Completely Fair Scheduler Prozesse A B C Gewichte 4 3 1 4/8 3/8 1/8 8 8 8 Summe = 8 CPU Zeit M. Esponda-Argüero Completely Fair Scheduler 27 17 33 6 Nil 2 Nil 24 Nil struct sched_entity{ struct load_weight load; struct rb_node run_node; struct list_head group_node; ... } 31 Nil Nil 29 Nil Nil 50 Nil Nil Nil O(log(n)) virtuelle Laufzeit braucht mehr CPU-Zeit braucht weniger CPU-Zeit M. Esponda-Argüero Multithreading-Architektur von Solaris Many-to-Many Thread-Modell M. Esponda-Argüero Thread-Scheduling Thread - Benutzer-Threads PCS - Kernel-Threads SCS Thread-Modelle - one-to-one - many-to-one - many-to-many PCS Process-contention scope SCS System-contention scope Prozess-Thread Threads werden auf sogenannte LWP Prozesse innerhalb des Kernels abgebildet. In dem SCS-Scheduling konkurrieren alle Threads des Systems für die CPU-Zeit. Kernel-Thread M. Esponda-Argüero Pthread-Scheduling Zwei Start-Attribute: PTHREAD_SCOPE_PROCESS Scheduling in PCS PTHREAD_SCOPE_SYSTEM Scheduling in SCS Linux und Mac OS X erlauben nur PTHREAD_SCOPE_SYSTEM Berücksichtigte Threads Zustellungs-Bereich Scheduling in SCS PThread-Scheduling Berücksichtigte Threads innerhalb von Prozessen Berücksichtigte Threads zwischen Prozessen Scheduling in PCS pthread_attr_setscope(pthread_attr_t *attr, int scope); pthread_attr_getscope(pthread_attr_t *attr, int *scope); Mehrfach-Prozessor Scheduling - Durch moderne Rechnerarchitekturen mit mehreren Prozessoren wird das Scheduling-Problem komplexer. - Wir konzentrieren uns auf Systeme mit gleichartigen parallelen Prozessoren. Asymmetrische - ein CPU (Master Server) für Systemaktivitäten und Mehrfach-Prozessor Scheduling - Ein-/Ausgabe-Aktivitäten. - andere Prozessoren nur für Benutzerprozesse. Symmetrische (SMP) - Die Prozessoren werden selber verplant oder jeder Prozessor hat seine eigene SchedulingWarteschlange M. Esponda-Argüero Mehrfach-Prozessor Scheduling Hart Affinität „Processor Affinity“ Kriterien für die CPU-Zuteilung Prozesse (Threads) können nur auf bestimmten Prozessoren laufen. Weich Prozesse (Threads) werden bevorzugt auf den Prozessoren laufen, wo sie zuletzt gelaufen sind. „push migration“ Lastverteilung „Load Balancing“ Ein Task prüft periodisch die Prozessorlast und teilt die Prozesse neu auf. „pull migration“ Ein unbelasteter Prozessor holt sich selber einen Prozess. M. Esponda-Argüero Kontext-Wechsel Direkte Kosten: - Speichern und Laden von Registern - Adressraum-Wechsel Indirekte Kosten: CPU-cache, File-/Page-cache und TLB-misses T1 CPU Cache T2 ErsetzungOverhead File/Page Cache M. Esponda-Argüero Multicore-Prozessor Scheduling Probleme: Memory stall Prozessoren warten häufig mehr als 50% der Zeit auf Speicher-Zugriffe Memory stall cycle Compute cycle Thread0 Thread1 C C M M C C M C M C M M C C M M C M Zeit Multithreaded multicore system Lösungen: - coarse-grained-Multithreading - fine-grained-Multithreading M. Esponda-Argüero Solaris Scheduling Das Solaris-Betriebssystem hat: - Unterstützung von Threads auf Benutzer- und Kernel-Ebene - Symmetrisches Multithreading - Echtzeit-Scheduling Solaris hat einen Scheduler mit Prioritäten und sechs SchedulingKlassen. 6 Fix Priority (FP) 5 Fair share (FSS) 4 Real Time (RT) 3 System (SYS) 2 Interactive (IA) 1 Time sharing (FP) Innerhalb jeder Klasse werden verschiedene Prioritäten und verschiedene Algorithmen verwendet. M. Esponda-Argüero Solaris Scheduling-Tabelle für time-sharing und interaktive Threads Die Prioritäten werden umgekehrt proportional zum Quantum vergeben. 60 Prioritätsebenen neue Prioritäten Bildquelle: Silverschatz Solaris Scheduling Scheduling-Reihenfolge Globale Priorität höchste 169 erste Interrupt-Threads 160 159 Real-Threads 100 99 System-Threads 60 59 niedrigste 0 Fair share-Threads Fixed priority-Threads Timeshare-Threads Interactive-Threads letzte Die Default-Klasse ist "time sharing". M. Esponda-Argüero Solaris Scheduling Globale Prioritäten Höchste Scheduling Reihenfolge Scheduling Klassen Erste Echtzeit AusführungsWarteschlangen Max . . . 0 . . . System . . . Kernel Echtzeit LWPs Kernel DienstThreads RR-Scheduling Interaktiv Time sharing Niedrigste Letzte Max . . . 0 . . . LWPs M. Esponda-Argüero Windows Vista Scheduling - kein zentraler Thread für das Scheduling - Wenn ein Thread nicht mehr weiter laufen kann, wechselt er selbst in den Kernmodus und ruft den Scheduler auf. Grund? -Das Quantum ist abgelaufen -Der Thread wird blockiert -Der Thread schickt ein Signal an ein Objekt Systemaufrufe: SetPriorityClass Setzt die Prioritäten aller Threads eines Prozesses. SetThreadPriority Legt die relative Priorität eines Threads bezüglich der Prioritätsklasse seines Prozesses fest. M. Esponda-Argüero Windows Vista Scheduling Win32 API Prioritätsklassen: REALTIME_PRIORITY feste Prioritäten HIGH_PRIORITY ABOVE_NORMAL_PRIORITY NORMAL_PRIORITY variable Prioritäten BELOW_NORMAL_PRIORITY IDLE_NORMAL_PRIORITY Vordergrund- / Hintergrund- Prozesse Relative Prioritäten innerhalb der Prioritätsklassen - TIME_CRITICAL HIGHEST ABOVE_NORMAL NORMAL BELOW_NORMAL LOWEST IDLE M. Esponda-Argüero Windows Vista Prioritäten Default Anfangsprioritäten Prioritätsklassen relative Prioritäten Bildquelle: Silverschatz Windows Vista Prioritäten - Insgesamt 32 Prioritäten (0-31). - Das Scheduling-System verwaltet ein Array mit 32 Thread-Listen. - 0-15 sind Benutzer-Prioritäten - 16-31 sind System-Prioritäten Anhebung von Prioritäten - Wenn I/O- Operationen beendet werden 1 Festplatte 2 eine serielle Verbindung 6 Tastatur 8 Soundkarte - Wenn ein Prozess auf Semaphore, Mutexe oder andere Ereignisse gerade gewartet hat ( 1-2 Stufen ) M. Esponda-Argüero Windows Vista Prioritäten Prioritäten werden kleiner - Wenn ein Thread sein Quantum beendet (1 Stufe) Weitere Veränderungen Das Scheduling-System verfolgt, wieviel Zeit vergangen ist, seit ein rechenbereiter Thread zuletzt gelaufen ist. Nachdem ein bestimmter Schwellenwert erreicht worden ist, wird seine Priorität um zwei Quanten erhöht, auf maximal 15. Prozesse, die in den Vordergrund gestellt werden, bekommen automatisch eine höhere Priorität. M. Esponda-Argüero Java - Scheduling Ein Java-Thread kann nur unterbrochen werden wenn: - sein Quantum abgelaufen ist - weil der Thread auf eine Ein-/Ausgabeoperation wartet - seine run-Methode zu Ende ausgeführt wurde Die yield-Methode kann einen Thread unterbrechen, auch wenn sein Zeitquantum noch nicht abgelaufen ist. Java-Threads haben eine Priorität von 0 bis 10. Die 0-Priorität kann nur direkt von der JVM vergeben werden. M. Esponda-Argüero Java - Scheduling Folgende Prioritätskonstanten sind definiert. Thread.MIN_PRIORITY 1 Thread.MAX_PRIORITY 10 Thread.NORM_PRIORITY 5 Je nachdem in welchem Betriebssystem die JVM läuft, haben Threads mit gleicher Priorität verschiedene Verhalten. Prioritäten in Java-Threads können mit Hilfe der setPriorityMethode verändert werden. M. Esponda-Argüero Systemaufrufe für Scheduling Linux Systemaufruf Beschreibung nice( ) Change the priority of a conventional process. getpriority( ) Get the maximum priority of a group of conventional processes. setpriority( ) Set the priority of a group of conventional processes. sched_getscheduler( ) Get the scheduling policy of a process. sched_setscheduler( ) Set the scheduling policy and priority of a process.sched_getparam( ) Get the scheduling priority of a process.sched_setparam( ) Set the priority of a process. sched_yield( ) Relinquish the processor voluntarily without blocking. sched_get_ priority_min( ) Get the minimum priority value for a policy. sched_get_ priority_max( ) Get the maximum priority value for a policy. sched_rr_get_interval( ) Get the time quantum value for the Round Robin policy