470 likes | 557 Vues
OPERÁCIÓS RENDSZEREK. Ütemezés és a Context Switch. A mai program. A CPU ütemezéshez fogalmak, alapok, stratégiák Időkiosztási algoritmusok VAX/VMS, NT, Unix időkiosztás A Context Switch implementáció. Fogalmak. Erőforrásokat Hozzárendelünk processzekhez (allokáció);
E N D
OPERÁCIÓS RENDSZEREK Ütemezés és a Context Switch
A mai program • A CPU ütemezéshez fogalmak, alapok, stratégiák • Időkiosztási algoritmusok • VAX/VMS, NT, Unix időkiosztás • A Context Switch implementáció Vadász
Fogalmak • Erőforrásokat • Hozzárendelünk processzekhez (allokáció); • A használatukat időben beosztjuk (időkiosztás, scheduling); • Kapcsoljuk azokat a kiosztott időpillanatban (dipatching és switch). • Most a processzor „üzemezésről” lesz szó • (Az egyéb erőforrás ütemezés kérdéskör a „kölcsönös kizárás’ probléma kezelésénél előjön majd …) • A CPU meglehetősen fontos (és jellegzetes) erőforrás. Érdemes ütemezését külön tárgyalni. Vadász
A probléma • Több processz van, mint processzor … • A processzek osztozzanak egy CPU idején. (Tegyük fel: minden processzhez rendeltek (ez az allokáció) egy CPU-t.) • Emlékezz a processz állapotokra: • ha letelt az időszelete a futó processznek, • Vagy ha maga blokkolt állapotba megy (ezzel „lemond” a CPU-ról), • akkor a futásra kész processzekből válasszunk ki egyet (ez a scheduling), és • „kapcsoljuk neki” a CPU-t (ez a dispathing és a Context Switch második fele). Vadász
Tágítjuk a problémát: ütemezési szintek • Long-term-scheduling (hosszútávú) • JOB ütemezés: JOB/taszk pool-ból melyiket válasszuk ki futásra. A multiprogramozási szintet befolyásolja. • Medium-term-scheduling (középtávú) • suspended (futásra nem kész, partially executed, outswapped) processzek közül melyeket helyezzük futásra késszé (memória igény is érdekes) • Short-term-scheduling (rövidtávú) • futásra kész processzek közül melyik kapja a CPU-t. • A továbbiakban ezzel foglalkozunk. (Ezzel ismét szűkítünk.) Vadász
Mit várunk el? • Pártatlanság: minden processz (taszk) korrekt módon, de nem feltétlenül egyenrangúan kapja meg a processzort • Hatékonyság: a CPU lehetőleg legnagyobb százalékban legyen kihasználva • Válaszidő (interaktív felhasználóknak): elfogadható legyen • Fordulási idő (kötegelt munkák): elfogadható legyen • Teljesítmény: időegységre eső JOB, taszk, processz feldolgozás (más, mint a CPU kihasználás!) jó legyen Látható ellentmondások! Vadász
Technikai alapok • Óraeszköz periodikusan megszakításokat generál • Az időt szeletekre (time slice, quantum) bonthatjuk • A CPU felhasználás idejét, a processzek életidejét stb. számon tarthatjuk • Bizonyos időnként az állapotokat kiértékelhetjük, és CPU kapcsolást valósíthatunk meg Vadász
Az óraeszköz • A programozható óra 3 komponensből áll: • oszcillátor kristály: nagy pontossággal periodikusan jeleket generál (tipikusan 5 - 100MHz). • Számláló (counter): ami dekrementálja az értékét minden a kristály által generált jelre. Mikor a számláló eléri a 0 értéket, IT generálódik. • Tartó regiszter (holding register): az óra indulásakor (one-shot mode) vagy a counter 0-vá válásakor (square-wave-mode) tartalma betöltődik a számlálóba, ezzel szabályozhatjuk, milyen gyakran keletkezzen IT (clock tick rate). • Pl. egy 1MHz-es kristály (1s-ként ad jelet), 16 bites regiszterekkel programozható 1s-től 65535 s-ig tartó óra ütés (clock-tick) tartományba. Vadász
Az óraeszköz IT kezelőjének feladatai • A napi idő karbantartása, • a futó processz által felhasznált CPU idő számolására, • a processz időkvantuma lejártának megállapítására, ütemező meghívására, • alarm szignál generálására (amikorra azt egy processz igényelte), • "watchdog timer"-t biztosíthat (pl. floppy kezelésnél: felpörgetés, lehet I/O; ugyanekkor indul a wd-timer, ami leállítja a pörgetést, ha nem jön újabb i/o kérés) • Segíti a profiling-ot, monitoring-ot, statisztikáz. Vadász
Napi idő karbantartás • Egy számláló (64 bites) a napi időt (time-of-day) nyilvántartja óra-ütésekben (clock-tick), vagy 2 számláló: sec-ben + "ütésszám a kurrens sec-ben" (32 bit a sec-nak, 16 bit tickeknek) • egy fix időhöz képest (Unix: 1970. jan 1. 12:00-tól) • a bootolási időtől (32 bit a tick-számlálónak, 32 bit a sec-ben mért betöltési időnek). • A rendszergazda által adott dátum-idő átszámítódik clock-tick-ekbe, és beíródik a számlálóba. • Az óra kezelő (clock driver, clock IT handler) ütésenként növeli ezt a számlálót (számlálókat) Vadász
CPU idő nyilvántartás • A processzhez tartozó számláló ütésenként inkrementálódik, ha a processz futó állapotú. • Megoldható, hogy külön számláljuk a felhasználói módú és a kernel módú CPU használatot (persze, kis hibák itt lehetnek). Az idő-szelet nyilvántartása • A quantum, time-slice nyilvántartáshoz a context switch esetén egy számlálót (akár processzenkénti számlálót) feltöltünk óra-ütésekben mért időszelet értékkel, majd ezt ütésenként dekrementáljuk. • A számláló 0-vá válása jelzi a quantum lejártát Vadász
Időzítő (alarm, watchdog-timer) Következő szignál Kurrens idő 4200 3 Clock header 3|S1 4|S2 6|S3 • Idők lejártát ütésekben (tickek-ben) adott számlálók 0-vá válása jelezheti. • Számlálók (órák) időben rendezett láncolt listáját tartjuk fel, a számlálókban a következő szignál ideje (tick-ben). • A lista elején lévő számlálót dekrementáljuk. • Pl. Kurrens idő: 4200, S1:4203, S2:4207, S3:4213 Vadász
Vissza az ütemezéshez: technikai alapok • Óraeszköz periodikusan megszakításokat generál • Az időt szeletekre (time slice, quantum) bonthatjuk • A CPU felhasználás idejét, a processzek életidejét stb. számon tarthatjuk • Bizonyos időnként az állapotokat kiértékelhetjük, és CPU kapcsolást valósíthatunk meg Vadász
Döntési stratégiák • Nem beavatkozó (non-preemptive) • run-to-completion jellegű • együttműködő (kooperative) • Szelektív beavatkozó • Beavatkozó (preemptive): akkor is elveszik a CPU-t egy processztől, ha az nem akar lemondani róla Vadász
Ütemezési döntési helyzetek • Egy processz wait állapotátmenete. • Egy processz preemption állapotátmenete (pl. megszakítás bekövetkezése miatt). • Egy processz signal állapotátmenete. • Egy processz terminálódása. (4) exit running schedule/run (1) sleep/wait/request (2) preempt (3) signal/assign blocked ready waiting Vadász
Ütemezési döntési helyzetek • Egy processz wait állapotátmenete. • Egy processz preemption állapotátmenete (pl. megszakítás bekövetkezése miatt). • Egy processz signal állapotátmenete. • Egy processz terminálódása. A processz szempontjából az 1. és 4. helyzet nem döntési helyzet. Az viszont a 2. és a 3. számú. Ha ütemezési döntések csak az 1., 4. helyzetekben lehetségesek: nem beavatkozó az ütemezés. Vadász
A leegyszerűsített forgatókönyv • A futó processz ideje lejárt (egy logikai óra, számláló lejárt, ütésére egy IT kezelő működésbe lép), vagy a futó processz blokkolt állapotba menne; • A kezelő (a sheduler) kiértékel, és kiválasztja a futásra kész processzekből a „nyertest” (ez egy prioritás számítás, optimum számítás); • Majd megtörténik a „kapcsolás” … Vadász
Mi befolyásolhatja a kiválasztást? • Prioritás = fontosság. Mi befolyásolhatja? • A processzek memóriaigénye • A processzek „érkezési ideje” vagy „érkezési sorrendje” • Az eddigi CPU felhasználási idő* • Vö.: CPU lázas processzek szemben I/O lázas processzek • A várható CPU felhasználási idő* • Vö.: Számolásigényes processzek szemben I/O igényes processzek. • Vajon lehet-e időt becsülni? • A processz „időszerűsége”** • Vö.: interaktív processzek szemben kötegelt munkák, • CPU lázas szakaszok szemben az I/O lázas szakaszok. • Rendszer terhelés befolyása. • Valós idejű processzek problémája kezelendő. Vadász
Egy kis fogalom magyarázat … • A processz életében lehetnek • CPU lázas időszakaszok (CPU burst) • I/O lázas időszakaszok (I/O burst) • Vannak • Számolásigényes (CPU bound) processzek (hosszú CPU lázas szakaszokkal); • I/O igényes (I/O bound) processzek (rövid CPU lázas szakaszok, sok I/O lázas szakasz). Vadász
Melyik ütemezési prioritása legyen magasabb? Fut Fut Ready Blokkolt Ready Blokkolt Egy processz állapotátmenetei CPU lázas időszakában Egy processz állapotátmenetei I/O lázas időszakában Vadász
Az ütemezési algoritmusok • Mi (milyen) a prioritásfüggvény? • Az igény-bejelentési sorrend (First Come, First Served) (Long- és Medium-term ütemezéshez) • A legkisebb igény (Shortest Job First) (Long- és Medium-term ütemezéshez) • Valamilyen ígéret (ígéret-vezérelt időkiosztás) (Policy Driven Scheduling) • Körkörös sorrend (Round-Robin Scheduling) • Több összetevőtől függő (Többszintes prioritás-sorokon alapuló visszacsatolásos) (Multilevel Feedback Queue Scheduling) Vadász
First Come, First Served • A processzek készletében (Process Pool) lévő processzek a beérkezési sorrendjük szerint kapnak CPU-t. • Egyszerű a megvalósítás. • Kialakulhat a „convoy effect”: korábban érkezett CPU lázas szakaszú processz lefogja a CPU-t. (Országúton lassú jármű mögött sorban a gyorsabbak) Vadász
Shortest Job First • Régi, egyszerű. • A nyomtató kiszolgálási sorokból ütemezésre még ma is használják. • Az átlagos fordulási idő a legkisebb. • CPU ütemezéshez: hogyan lehetne megmondani előre a várható időigényt? • Idősorozatokkal jellemezhető munkákhoz az aging (öregedés) algoritmus. Vadász
“Aging “ algoritmus 0, 1, 2, ...,i,.. CPU lázas szakaszok ismétlődnek (nem egyforma időt igényelve). Becsülhetjük a következő idejét (Ti : tényleges, mért; Bi: becsült): Bi+1 = a * Ti + (1 - a) * Bi ; ahol 0 <= a <= 1. Legyen a = 1/2, ekkor (a: súlyozó faktor) Bi+1 = (Ti + Bi ) / 2 Vadász
Policy Driven Scheduling • Reális ígéret: n számú processz esetén 1/n-ed részét kapja egy processz a CPU-nak. • Mérni kell az • élet-idő-t (a rendszerben eddig eltöltött idejét), és • cpu-idő-t (eddig felhasznált CPU időt), számítandó a • jogosultsági-idő = élet-idő / n; • prioritás = jogosultsági-idő / cpu-idő. • Más ígéretek is lehetnek • Az ígéret-vezérelt időkiosztás speciális esete a valós idejű (Real Time) időkiosztás. Vadász
Round Robin Egyszerű, elég régi algoritmus. Időszeleteket (quantum) rendelünk a processzekhez. • A kész állapotú processzek egy soron nyilvántartottak. • Egy processz futhat, amíg a időszelete tart (ha blokkolódik, akkor addig sem fut). • Lejárt szeletű (preempted) processz a sor végére kerül. • A sor elején álló kapja a CPU-t. A listán a processzek “körben“ járnak. Vadász
Multilevel Feedback Queue Scheduling • Több ready sor van, a különböző prioritási szintekhez • Elvileg lehet minden sorhoz más-más scheduling/prioritás algoritmus • Pl. interaktív processzekhez preemptív FCFS, vagy MLFQ • Batch processzekhez SJF • Valós idejű (Real Time) processzekhez fix prioritás • Minden sorhoz rendelhetünk időszeletet • Kell egy módszer: mikor, mennyivel csökkentsük a prioritást • Kell egy módszer (algoritmus), mikor mennyivel növeljük a prioritást (visszacsatolás) • Preempted/blocked/signaled processz a neki megfelelő sor végére kerüljön • Kell egy módszer, melyik sorról "kapcsoljunk" • Pl. a legegyszerűbb: a legmagasabb sorról az elsőt. Vadász
VAX VMS scheduling • Multilevel feedback jellegű, alkalmas real time-ra is. • 32 prioritási szint. Nagyobb szám: nagyobb prioritás. • 16-32: a valós idejű processzek számára. Nem dinamikus! • 0-15: reguláris processzeknek, dinamikusan számítódik. • A processz bázis-prioritása: minimális prioritása. • Rendszerhívásokhoz rögzített prioritás növekmény. Mikor a processz futásra késszé válik, a növekmény hozzáadódik a bázis-prioritáshoz, és a megfelelő sorra kerül processz. • Scheduled processz prioritása egy szinttel csökken (határ a bázis-prioritás). Ha elveszik tőle a CPU-t, erre az új sorra kerül. • Sokáig várakozókat eggyel följebb emelik (no starvation). • A scheduler a legmagasabb prioritás sor elejéről választ. Vadász
Unix időkiosztás 0 Kernel mód prioritás-tartomány Küszöb prioritás User mód prioritás-tartomány n Vadász
A Unix időkiosztása • A processzeknek user-mode vagy kernel-mode prioritásértéke lehet. Az előző dinamikus, ezek lehetnek preempted processzek. Utóbbi fix érték. Ezekre nincs preempció. • Küszöb prioritás szint elválaszt. • A user-mode prioritások (p_usrpri) dinamikusan “igazítódnak“. • A p_cpu mező a futó processznél a CPU használattal arányosan nő. • A p_cpu mezőt quantumonkként öregbítik (aging): p_cpu = p_cpu / const1; (rendszerint const1 = 2). Vadász
A Unix időkiosztása2 • A prioritás kiszámítódik (kisebb érték jelenti a nagyobb prioritást!): p_usrpri=PUSER+p_cpu/const2 + p_nice/const3; (Rendszerint const2=const3=2;). • A PUSER a processz bázisprioritása, külső prioritás. • A p_nice a nice() rendszerhívással (felhasználói kontrollt lehetővé tevő) beállított érték. • A p_usrpri a küszöb érték alá, egy beállított érték fölé nem mehet. Vadász
Egy példa Egy rendszerben a PUSER=60. Ha egy processz megkapja a CPU-t és quantumában végig használja, a p_cpu növekmény legyen 60. Legyen 3 processz (A, B, C), induláskor a C p_cpu-ja 7, a másik kettőé 0. Induláskor a p_uspri C-nél 63, a másik kettőnél 60. Mindhárom processznél a p_nice érték 0 legyen. Követhetjük, hogyan változnak a prioritások, melyik processz kap CPU-t. Vadász
BSD 4.3 Scheduling • Quantum=0.1 sec; const2=4; const3=2; • const1 dinamikusan számítódik: • const1=(2*load+1)/(2*load); ahol • load a run queue álagos hossza az utóbbi 1 percben • Ugyanekkor a p_cpu öregbítés nem quantumonként, hanem 1 sec-enként történik csak! • Az 1 sec-nél hosszabb ideig blokkolt processzeknél • const1 a blokkolási időtől is függ! Vadász
NT Scheduling a fonalakra • Van standby állapot is: a legnagyobb prioritású futásra kész. A standby-t ütemezik ki. • 32 prioritási szint, 16-31: valósidejű, 0-15: normál, változó (mint a VAX/VMS-nél) • Lejárt quantumú fonál prioritás 1-gyel csökken (a bázisig). • Kész állapotba jutó fonál prioritása növekszik, a blokkolódása típusától függően • A legmagasabb kész sor első fonala standby állapotúra változik. Ha nincs ilyen, az idle fonál lesz standby. Vadász
Linux scheduling • A POSIX 1003.4-nek megfelelően több ütemezési osztály van (processzenként beállítható) • SCHED_FIFO, SCHED_RR, SCHED_OTHER • A schedule() függvény hívódik • ha processz blokkolt állapotba megy, • Minden syscall és "slow" IT után, ha egy flag beállított. • A schedule() függvény 3 dolgot csinál • "szokásos" teendőket (miknek az óra IT kezelőben kellene lenniük, de "hatékonyság" miatt itt vannak) • Legmagasabb prioritású processz meghatározása • Context Switch Vadász
A CPU allokálás: Context Switch • A futó processz hardver kontextusát (dinamikus részét) lementjük valahová, • a kiválasztott processz kontextusát felvesszük. • Legfontosabb a programszámláló (PC, IP) lementése, felvétele. • Lementés történhet • wait (blokkolódás) állapot-átmenetnél, vagy • preemption állapot-átmenetnél is. • A felvétel schedule átmenetet okoz. Vadász
Hova mentsük le a dinamikus kontextust? Lehetne • a Process Table sorába (PCB-be). Hátrány: nagy lesz a tábla, a lementés/felvétel hardveresen nem támogatott. • Veremtárba. Előny: hardveres push/pop is van. • Felhasználói szintű verembe? Nem. • Közös kernel verembe? • Processzenkénti kernel verembe? • Egyes CPU-kban többszörös regiszterkészlet! • Egyes CPU-knak van védett módú processz kapcsolás gépi instrukciójuk! Vadász
Unix processz kontextus komponensek A kontextus statikus része A kontextus dinamikus (volatile)része Felhasználói szintű kontextus • Program szöveg • Adatok • Veremtár • Osztott adatok Keret a 3. rétegnek Rendszer szintű kontextus statikus része Keret a 2. rétegnek • Process Table bejegyzése • U Area • Processzenkénti Region Table Keret az 1. rétegnek Felhasználói szint Vadász
Egy lehetséges mechanizmus • Lásd a Unix processz kontextus ábrát (előző dia): keretek a processz kernel veremben a dinamikus kontextus részére. • Hány keret kell? Mikor keletkezik új réteg? • rendszerhívással (trap) belépünk a kernelbe; • megszakítással belépünk a kernelbe; • preemption következett be. • Megszűnik egy réteg, ha • rendszerhívásból visszatérünk user szintre; • megszakítás kiszolgálásból vissztérünk; • schedule átment következett be. Vadász
A kapcsolás lépései • Döntés, legyen Context Switch. • A save-context() algoritmussal a kurrens processz dinamikus kontextusának lementése; • A “legjobb“ processz kiválasztása (scheduling algoritmusok!) • A resume-context() algoritmussal a kiválasztott processz kontextusának felvétele. Tételezzük fel: R0 regiszterben van a függvények visszatérési értéke, PC a programszámláló, PSW a státus regiszter. Ezekre van hardveres push/pop. Vadász
Pszeudókódok1 int save_context() { R0 0; SWIT { HW-PUSH(PC,PSW); PUSH (altalanos regiszterek); /* lementődött a keret, R0=0-val */ R0 (-1); JUMP Return-re; } Return(R0); } /* A HW-PUSH-nál a PC a Return-re mutat. Látjuk majd, két visszatérés van ebből. Először a JUMP Return miatt (R0=-1-gyel), másodszor a PC felvétele miatt (de akkor előtte az R0-t is felveszik, az meg 0 lesz, tehát R0=0-val). */ Vadász
Pszeudókódok2 int resume_context(pid_t pid) { A pid-del azonosított processz verméről vedd vissza az általanos regisztereket; POP PSW; POP PC; /* ide a vezérlés nem juthat el */ } /* Miért nem jut oda a vezérlés? Mert a visszavett PC a save_context Return-jére mutat! */ Vadász
A Context Switch pszeudókódja ... if (save_context()) { Ütemezz másik processzt, ennek pid-je = new_pid; resume_context(new_pid); /* ide a vezérlés nem juthat el */ } ... /* Innen futhat a visszavett kontextusú processz */ /* Ne feledjük, a save_context-ből két visszatérés is van: az if-nek először nem-nulla értéket ad (és belefut a schedulingba), másodszor 0-val visszatérve kikerüli azt. */ Vadász
A vezérlés menete … A B IT D S Ü R 2nd IRET Dönt; if(save_context( )) { npid = Ütemez; Resume_context(npid); } 2nd; Vadász
Volt már ilyen, emlékezzünk ... #include <setjmp.h> jmp_buf env; int i = 0; main () { if (setjmp(env) != 0) { (void) printf("2nd from setjmp: i=%d\n", i); exit(0); } (void) printf("1st from setjmp: i=%d\n", i); i = 1; g(); /*NOTREACHED*/ } g() { longjmp(env, 1); /*NOTREACHED*/ } Vadász
Összefoglalás • Foglakoztunk az • Alapokkal, stratégiákkal • Időkiosztási algoritmusokkal • VAX/VMS, NT, Unix időkiosztással • A Context Switch implementációval Vadász
OPERÁCIÓS RENDSZEREK Ütemezés és a Context Switch Vége