Scheduling Teil 2

Prof. Dr. Margarita Esponda Freie Universität Berlin WS 2011/2012 Multilevel Feedback Queue 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 0 20 ich bin nicht nett und er will gleich ich bin sehr nett und will mehr CPU-Zeit bleiben gibt CPU-Zeit ab

der Prioritätszerfall die Prioritätszerfall wird gebremst wird beschleunigt

M. Esponda-Argüero BSD 5.2 - Scheduler Scheduling-Klassen

Priorität Klasse -Type

0 - 63 ITHD Botton-half kernel (Interrupt)

63 - 127 KERN Top-half kernel 160

128 - 159 REALTIME Real Time 161

162

160 - 223 TIMESHARE Time-sharing user ......

224 - 255 IDLE 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 CPU- Zeit

✴ 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

2 ⋅ avg _loadt recent _ cput = 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.

i=t −60 length(run _ queue i ) + length(wait _ queuei ) avg _load = ∑i=t t 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:

sleep _ time ⎛ 2 ⋅ avg _load ⎞ t recent _ cpu t recent _ cpu nice t = ⎜ ⎟ t −1 + ⎝ 2 ⋅ avg _loadt + 1⎠

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 = T = 0,66 ⋅T 3 0 0

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 Server- Prozess 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 "

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 CPU- Zuteilungen 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

Beispiel: stride1

stride1 = 20 strideTi = ticketsTi

Am Anfang ist der pass-Wert = 0 für alle Prozesse

Der Scheduler wählt den Prozess mit dem kleinsten pass-Wert 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.

stride global _ stride = 1 global _tickets

pass global _ pass stride Tnew = + Tnew M. Esponda-Argüero Stride-Scheduling

Prozesse haben auch eine remain-Komponente, die wie folgt berechnet wird: remain pass global _ pass = Ti −

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.

time pass pass consumed stride Ti = Ti + ⋅ Ti timeallocated

M. Esponda-Argüero Stride-Scheduling pass Anfangszustand der Warteschlangen HEAD 0 A B C

1 2 3 5 2 Tickets . . . n

0 . . A B C C B C A C B C . pass 15 10 6 12 20 18 30 24 30 30 HEAD 6 C . . time . 10 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

Priorität Quantum - real-time-Bereich 0 - 99 Höhere Prioritäten 200 ms. … - nice-Bereich 100 - 140 Niedrige Prioritäten 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 Bereit- Zustand sind, werden mit einem einzigen R/B-Baum verwaltet.

Jede CPU hat einen eigenen Scheduler mit einem eigenen R/B- Baum.

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 Summe = 8

4/8 3/8 1/8

CPU Zeit

M. Esponda-Argüero Completely Fair Scheduler

Prozesse A B C

Gewichte 4 3 1 Summe = 8

4/8 3/8 1/8

CPU Zeit

100% 100% 100%

M. Esponda-Argüero Completely Fair Scheduler

Prozesse A B C

Gewichte 4 3 1 Summe = 8

4/8 3/8 1/8

CPU Zeit

8 8 8

M. Esponda-Argüero Completely Fair Scheduler struct sched_entity{ struct load_weight load; 27 struct rb_node run_node; struct list_head group_node; ... 17 33 }

6 24 31 50

Nil Nil Nil 2 Nil 29 Nil Nil

Nil 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 Thread-Modelle

- Benutzer-Threads PCS - one-to-one - Kernel-Threads SCS - many-to-one - many-to-many

PCS -contention scope SCS System-contention scope Prozess-Thread

Threads werden auf sogenannte LWP Prozesse innerhalb des Kernels abgebildet.

In dem SCS-Scheduling Kernel-Thread konkurrieren alle Threads des Systems für die CPU-Zeit.

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 Berücksichtigte innerhalb von Threads zwischen Prozessen 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 - Ein-/Ausgabe-Aktivitäten. Mehrfach-Prozessor - andere Prozessoren nur für Scheduling Benutzerprozesse. Symmetrische (SMP)

- Die Prozessoren werden selber verplant oder jeder Prozessor hat seine eigene Scheduling- Warteschlange

M. Esponda-Argüero Mehrfach-Prozessor Scheduling

Hart Prozesse (Threads) können nur auf bestimmten Affinität Prozessoren laufen. „“ Weich Prozesse (Threads) werden bevorzugt auf den Prozessoren laufen, wo sie Kriterien für die zuletzt gelaufen sind. CPU-Zuteilung „push migration“ Ein Task prüft periodisch die Lastverteilung Prozessorlast und teilt die Prozesse neu auf. „Load Balancing“ „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 T2

CPU Cache Ersetzung- Overhead

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 M

Compute cycle C

Thread0 C M C M C M C M

Thread1 C M C M C 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 Scheduling- Klassen. 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 Globale Priorität Scheduling-Reihenfolge

höchste 169 erste Interrupt-Threads 160 159

Real-Threads

100 99 System-Threads

60 59 Fair share-Threads Fixed priority-Threads Timeshare-Threads niedrigste Interactive-Threads letzte 0

Die Default-Klasse ist "time sharing". M. Esponda-Argüero Solaris Scheduling

Globale Scheduling Scheduling Ausführungs- Prioritäten Reihenfolge Klassen Warteschlangen

Höchste Erste Max Echtzeit . Kernel . . . Echtzeit . . LWPs 0

System Kernel . Dienst- . Threads .

RR-Scheduling Max Interaktiv . . Time sharing . . LWPs . . Niedrigste Letzte 0

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 Vordergrund- / IDLE_NORMAL_PRIORITY 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 setPriority- Methode 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 . 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